Skip to content

avoiding allocations in FieldCollectorParameters and MergedField#2074

Merged
bbakerman merged 2 commits into
graphql-java:masterfrom
dfa1:field-collector-allocations
Oct 21, 2020
Merged

avoiding allocations in FieldCollectorParameters and MergedField#2074
bbakerman merged 2 commits into
graphql-java:masterfrom
dfa1:field-collector-allocations

Conversation

@dfa1

@dfa1 dfa1 commented Oct 15, 2020

Copy link
Copy Markdown
Contributor

ExecutionContext uses immutable maps for variables and fragments, that could be shared freely.

And, since this is an internal class, we could change a bit the contract and avoid some allocations of LinkedHashMap:

            .fragments(executionContext.getFragmentsByName())
            .variables(executionContext.getVariables())

@dfa1 dfa1 changed the title avoiding some LinkedHashMap allocations in FieldCollectorParameters avoiding allocations in FieldCollectorParameters and MergedField Oct 15, 2020
@dfa1

dfa1 commented Oct 15, 2020

Copy link
Copy Markdown
Contributor Author

For MergedField:

image

ArrayList allocated in the Builder never escapes the builder, so
it is possible to avoid one copy in the private ctor
@dfa1 dfa1 force-pushed the field-collector-allocations branch from 9e6ff2a to ee6ed0d Compare October 15, 2020 07:05
public Builder fields(List<Field> fields) {
this.fields = fields;
this.fields.addAll(fields);
return this;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

used only in tests, could be a breaking change.

Maybe this is the root cause of the additional copy that I've just removed in the constructor.

@bbakerman bbakerman added this to the 16.0 milestone Oct 19, 2020
public Builder variables(Map<String, Object> variables) {
this.variables.putAll(variables);
this.variables = variables;
return this;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a tricky one - generally we try for more immutable classes and hence by "copying" we gain some control in mutable Java land

However as this class is repeatedly called, we probably need to change this general pattern if we see evidence that it costs us.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I'm not sure too. I did that because the class is marked as @internal (so we may have more freedom) but I know that it is against the pattern mutable/builder -> immutable/built object.

It looks like it is always called with ExecutionContext data, that is unmodifiable.

@bbakerman bbakerman merged commit 31f44d8 into graphql-java:master Oct 21, 2020
@dfa1

dfa1 commented Oct 21, 2020

Copy link
Copy Markdown
Contributor Author

Thank you @bbakerman!

I just integrated this new version and run it under the memory profiler. Results are a bit better (1-2%):
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants