-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Fields will merge to AST visitor #1824
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
Conversation
Preliminary benchmarks: Master:
This branch:
|
(For those keeping score at home, about 25% faster 😎 ) |
After some caching, hard to say if it's much better, but I think the benches we have don't necessarily require caches so that's probably why.
|
Yeah, I bet "big query" benefited the most, I think it has lots of fragments. |
And another bench mark, I think this should be ready for review!
|
wow! I will review carefully next week |
context.errors << GraphQL::StaticValidation::Message.new(msg, nodes: node.ast_nodes.to_a) | ||
end | ||
def fields_and_fragments_from_selection(node, parent_type:) | ||
@fields_and_fragments_from_node[node] ||= begin |
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.
Fields and Fragment Spreads are collected once per node, iterating over the list only one.
Great context here from graphql-js: graphql/graphql-js#1497 (comment) Sounds like graphql-js doesn't handle these edge cases, and the spec doesn't seem to either 🤔 |
After trying a few things, I've just realized that: {
pet {
... on Dog {
... on Pet {
name
}
}
... on Cat {
name(surname: true)
}
}
} Used to be valid (Not sure how internal representation used to handle that case), but is not anymore. The algo probably has to maintain lists of parents instead of only the immediate parent of fields, in this case, |
The implementation of that was in |
(I'm surprised there wasn't a test for it!) |
With new algorithm, minus caching for now. Not a terrible change performance wise it seems
|
what a relief, still the same huge improvement over master! |
shoot, i really screwed up 1.9-dev, let me straighten it out and try to fix this branch. |
20d12cb
to
48bb6ba
Compare
Wow, I spent some time reading the code, thanks again for your amazing work here! 🎊 An interesting take-away for me is how iterative this implementation is. I mean, the comparison really boils down to looping over two sets and comparing each member to each other member. I wouldn't have guessed that it would be so fast, but it sure is. I would have used a Hash, but as shown in any profiler output for GraphQL-Ruby, I have an outstanding question, but it doesn't block merging this PR. Let's say we have a query like this: {
a { x y }
b { x y }
} When we enter Then, when we enter Also, I see that |
Converts the FieldsWillMerge validator to a "pure AST" validator, without using the rewrite. Most of the logic is based on the algorithm in graphql-js (https://github.com/graphql/graphql-js/blob/master/src/validation/rules/OverlappingFieldsCanBeMerged.js)
The algorithm is explained through comments in the class.