-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Avoid repeated calls to getFieldDef and unnecessary immutable builders/collections #3478
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| package graphql.execution; | ||
|
|
||
| import com.google.common.collect.ImmutableList; | ||
| import graphql.ExecutionResult; | ||
| import graphql.ExecutionResultImpl; | ||
| import graphql.PublicApi; | ||
|
|
@@ -66,7 +67,7 @@ public String toString() { | |
| public static class Builder { | ||
| private CompleteValueType completeValueType; | ||
| private CompletableFuture<Object> fieldValueFuture; | ||
| private List<FieldValueInfo> listInfos = new ArrayList<>(); | ||
| private List<FieldValueInfo> listInfos = ImmutableList.of(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have another PR that intends to break this class away from a builder pattern eg JUST allocate the the object - not a builder and then the object say
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was also going to add a |
||
|
|
||
| public Builder(CompleteValueType completeValueType) { | ||
| this.completeValueType = completeValueType; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,10 +13,12 @@ | |
| @PublicApi | ||
| public class MergedSelectionSet { | ||
|
|
||
| private final ImmutableMap<String, MergedField> subFields; | ||
| private final Map<String, MergedField> subFields; | ||
| private final List<String> keys; | ||
|
|
||
| protected MergedSelectionSet(Map<String, MergedField> subFields) { | ||
| this.subFields = ImmutableMap.copyOf(Assert.assertNotNull(subFields)); | ||
| this.subFields = subFields == null ? ImmutableMap.of() : subFields; | ||
| this.keys = ImmutableList.copyOf(this.subFields.keySet()); | ||
| } | ||
|
|
||
| public Map<String, MergedField> getSubFields() { | ||
|
|
@@ -40,7 +42,7 @@ public MergedField getSubField(String key) { | |
| } | ||
|
|
||
| public List<String> getKeys() { | ||
| return ImmutableList.copyOf(keySet()); | ||
| return keys; | ||
| } | ||
|
|
||
| public boolean isEmpty() { | ||
|
|
@@ -52,10 +54,10 @@ public static Builder newMergedSelectionSet() { | |
| } | ||
|
|
||
| public static class Builder { | ||
| private Map<String, MergedField> subFields = ImmutableMap.of(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok defaulting happening in constructor 👍 |
||
|
|
||
| private Builder() { | ||
| private Map<String, MergedField> subFields; | ||
|
|
||
| private Builder() { | ||
| } | ||
|
|
||
| public Builder subFields(Map<String, MergedField> subFields) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -44,7 +44,7 @@ public class GraphQLObjectType implements GraphQLNamedOutputType, GraphQLComposi | |
| private final String name; | ||
| private final String description; | ||
| private final Comparator<? super GraphQLSchemaElement> interfaceComparator; | ||
| private final ImmutableMap<String, GraphQLFieldDefinition> fieldDefinitionsByName; | ||
| private final Map<String, GraphQLFieldDefinition> fieldDefinitionsByName; | ||
| private final ImmutableList<GraphQLNamedOutputType> originalInterfaces; | ||
| private final DirectivesUtil.DirectivesHolder directivesHolder; | ||
| private final ObjectTypeDefinition definition; | ||
|
|
@@ -82,9 +82,9 @@ void replaceInterfaces(List<GraphQLNamedOutputType> interfaces) { | |
| this.replacedInterfaces = ImmutableList.copyOf(sortTypes(interfaceComparator, interfaces)); | ||
| } | ||
|
|
||
| private ImmutableMap<String, GraphQLFieldDefinition> buildDefinitionMap(List<GraphQLFieldDefinition> fieldDefinitions) { | ||
| return ImmutableMap.copyOf(FpKit.getByName(fieldDefinitions, GraphQLFieldDefinition::getName, | ||
| (fld1, fld2) -> assertShouldNeverHappen("Duplicated definition for field '%s' in type '%s'", fld1.getName(), this.name))); | ||
| private Map<String, GraphQLFieldDefinition> buildDefinitionMap(List<GraphQLFieldDefinition> fieldDefinitions) { | ||
| return FpKit.getByName(fieldDefinitions, GraphQLFieldDefinition::getName, | ||
| (fld1, fld2) -> assertShouldNeverHappen("Duplicated definition for field '%s' in type '%s'", fld1.getName(), this.name)); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yup - just checked - this does not change the immutability of what we give out since we never give out the map of fields directly
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That said building object types is done once per schema - so this really wont affect runtime query performance at all I think - or is ImmutableMap lookup of fields somehow slower ???
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah,
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I should add, this matters less than when I started working on this, because I found I could reduce the calls from 3 to 1, but it'll still help. |
||
| } | ||
|
|
||
| @Override | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,6 +21,10 @@ | |
| import org.openjdk.jmh.annotations.OutputTimeUnit; | ||
| import org.openjdk.jmh.annotations.Warmup; | ||
| import org.openjdk.jmh.infra.Blackhole; | ||
| import org.openjdk.jmh.runner.Runner; | ||
| import org.openjdk.jmh.runner.RunnerException; | ||
| import org.openjdk.jmh.runner.options.Options; | ||
| import org.openjdk.jmh.runner.options.OptionsBuilder; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
@@ -128,8 +132,14 @@ protected Optional<Object> getPersistedQueryId(ExecutionInput executionInput) { | |
| } | ||
| } | ||
|
|
||
| public static void main(String[] args) { | ||
| ExecutionResult result = execute(); | ||
| System.out.println(result); | ||
| public static void main(String[] args) throws RunnerException { | ||
| Options opt = new OptionsBuilder() | ||
| .include("benchmark.TwitterBenchmark") | ||
| .forks(1) | ||
| .warmupIterations(5) | ||
| .measurementIterations(10) | ||
| .build(); | ||
|
|
||
| new Runner(opt).run(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. question - I noticed you put I ask because we have a desire to do this some how (we worked with Twitter on this until Elon Husk wrecked the joint)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This makes it easier to iterate from the IDE and profile, setting the forks to |
||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The old code is left in place
and the engine only now calls the private method here. This means we dont break backwards compatibility. So nominally a 👍
HOWEVER - we have long had the debate inside the team about JUST how much API contract we should have in the ExecutionStrategy land - eg can other compose their own engines based on using the base classes and I think the answer is... they really cant make whole new engines using this class via inheritance and hence perhaps these should not be API per say
So it might be prudent @andimarek to just change the method signature - since the old method is dangling and never called by the engine now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, with the class marked
@PublicSpiI didn't want to mess with the signatures, and three remaining references internally: