Skip to content
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

improve overlapping fields performance #2495

Merged
merged 7 commits into from
Aug 2, 2021

Conversation

andimarek
Copy link
Member

@andimarek andimarek commented Aug 1, 2021

This is a rewrite of the overlapping field can be merged validation, which is quite slow for very large queries.

It is based on the article https://tech.xing.com/graphql-overlapping-fields-can-be-merged-fast-ea6e92e0a01 by @SimonAdameit. Thanks a lot @SimonAdameit for this!

For reference: it is basically the algorithm shown in Listing 10 adapted to the GraphQL Java codebase. I added some basic caching, but it is not equal to Listing 11 in the article.

Performance improvements (on my laptop):

350.048 ± 27.135 ms/op average time vs 35.927 ± 2.913 ms/op

for OverlappingFieldValidationBenchmark.

@andimarek andimarek added this to the 17.0 milestone Aug 1, 2021
GraphQLType graphQLType = inlineFragment.getTypeCondition() != null
? TypeFromAST.getTypeFromAST(getValidationContext().getSchema(), inlineFragment.getTypeCondition())
: parentType;
collectFields(fieldMap, inlineFragment.getSelectionSet(), graphQLType, visitedFragmentSpreads);
Copy link
Member

Choose a reason for hiding this comment

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

GraphQLType graphQLType = TypeFromAST.getTypeFromAST(getValidationContext().getSchema(),
fragment.getTypeCondition());

GraphQLType graphQLType = inlineFragment.getTypeCondition() != null
? TypeFromAST.getTypeFromAST(getValidationContext().getSchema(), inlineFragment.getTypeCondition())
: parentType;

The above repeated code deserves a method

Copy link
Member Author

Choose a reason for hiding this comment

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

done ...
just for the record: this is the same code as before: I didn't touch this part for this PR.

On a general note: this is very old code. In general there is a huge overlap in logic between FieldCollector, OverlappingField validation and the normalized field factory.

public FieldPair(Field field1, Field field2) {
this.field1 = field1;
this.field2 = field2;
return field != null ? field.equals(that.field) : that.field == null;
Copy link
Member

Choose a reason for hiding this comment

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

This .equals some suspect.

I mean you may only ever compared them into terms of AST Field equality - but the class itself has 3 fields

I just want to make sure this is intended

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes that is intended: the AST field is unique and actually determines the types, meaning we only need to compare the fields.

@andimarek andimarek merged commit c7154f8 into master Aug 2, 2021
// return changeNode(context, node.transform(builder -> builder.value(BigInteger.valueOf(intValueCounter.getAndIncrement()))));
// }
//

Copy link
Member

Choose a reason for hiding this comment

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

Was this meant?

Copy link
Member Author

Choose a reason for hiding this comment

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

deleting commented out code .. not directly related to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance work that is primarily targeted as performance improvements
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants