-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Speed up one_of?
#4680
Speed up one_of?
#4680
Conversation
Thanks for running the tests, I thought they passed but I must’ve missed something. I’ll take a look. Marking this as draft until then. |
c7ef97e
to
27831f3
Compare
The tests failures were cases where the I also built a benchmark to show the gains: Before:
After:
|
Hey, thanks for this suggestion. I'm all for performance improvements. The only thing that gives me the willies is
That would help me sleep better at night -- avoiding |
That sounds like a sensible approach to me. In this case I think the perf hit from The tradeoff is that |
I can believe it, but, what about, say, the |
27831f3
to
8044c96
Compare
Updated with your suggestion 👍, tests should be green, at least they were on my machine. |
Speed up `one_of?` by defining it as `false`, and when `one_of` is used, redefining the method as `true`. In profiles, I noticed that `oneOf?` was taking _some_ time. Looping through the directive list each time feels wasteful. This approach borrows from Rails' `Class#class_attribute` and redefines the `one_of?` when calling the `one_of` class method. This respects the fact that directives are inherited from parent classes; so is the `one_of?` class method. That said, this is not 100% backward compatible because users could be adding the OneOf directive without using the `one_of` DSL, but... it still feels pretty safe?
8044c96
to
add0de4
Compare
@@ -6,6 +6,18 @@ class OneOf < GraphQL::Schema::Directive | |||
description "Requires that exactly one field must be supplied and that field must not be `null`." | |||
locations(GraphQL::Schema::Directive::INPUT_OBJECT) | |||
default_directive true | |||
|
|||
def initialize(...) |
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 gem now supports Ruby 2.7+, so this should work. Feel free to change it to something else if you prefer.
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.
🙀 Beautiful, I bet there are many other places in this library that would benefit from this. What a time to be alive!
Thanks for this improvement! |
Speed up
one_of?
by defining it asfalse
, and whenone_of
is used, redefining the method astrue
.In profiles, I noticed that
oneOf?
was taking some time. Looping through the directive list each time feels wasteful.This approach borrows from Rails'
Class#class_attribute
and redefines theone_of?
when calling theone_of
class method. This respects the fact that directives are inherited from parent classes; so is theone_of?
class method. That said, this is not 100% backward compatible because users could be adding the OneOf directive without using theone_of
DSL, but... it still feels pretty safe?I didn't see a benchmark that had a lot of input, and in
rake bench:query
, the results are well within the margin of error. In a benchmark in our app though, where we're only validating a Hash against a GraphQL type, this made a difference.