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.
I was profiling some code that handles json_api_client results, and makes a lot of use of the dynamic attribute methods. I noticed that if I just implemented my own getter methods:
...then it got surprisingly faster.
I looked at the source, and spotted a few optimizations I could make. Here are 4, each with before/after benchmark times (the benchmark code is committed here as a unit test, which we can yank or move before this is merged).
The only commit without benchmark times is the change to use
end_with?('=')
instead of=~ /^(.*)=$/
, because it didn't actually speed it up. I committed it here as a curiosity; because I thinkends_with?('=')
is clearer than the regex; and because I've seen people say that it's faster, so this heads off the conversation.Probably the most controversial optimization is the last one: to auto-define getter methods for attributes from
DynamicAttributes#method_missing
. This is a significant speed-up: basically, we'll never have to run that method_missing logic again for that method name. Since the classes already respond to those methods, and handle those messages in an equivalent (but slower) way, this seems OK to me. Also, I don't think we have to worry about overwriting client code, because by definition, if#method_missing
is running, then they didn't define this one.Here's the overall benchmark difference, from the first commit (which only adds the benchmark unit test), to the last (with the 4 optimizations):
Before:
After: