Avoid Hash#merge on large subclass schemas #4664
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
It was already mentioned in the code how a large schema can incur a costly
Hash#merge
when using.references_to
:graphql-ruby/lib/graphql/schema.rb
Lines 553 to 555 in 9eee764
But the implementation there didn't address when a schema did have some inherited types. In that case, the cost was still paid of merging the hashes, even for a very small query.
We can re-work this, improving an existing implementation of
.references_to(type_name)
, so that the big, merged hash isn't used by GraphQL-Ruby execution, so it's never made at all.For a small schema with inherited types, it can make a big difference. The benchmark I added here:
That was one object taking up 10% of memory!
Another thing I noticed was that, because the
@references_to
Hash was assigning[]
to keys by default,GraphQL::Schema
could actually have some entries in its Hash. But they might not point at anything -- they might just be misses. So it would cause.merge
for a bunch of empty arrays 😩TODO:
Warden#referenced?
references_to
so they weren't performing themerge
to start with.