Do not call #class from #hash to imorove performance #906
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.
This PR improves performance by removing
self.class.hash
method calls fromhash
methods.Profiling
I profiled
rbs validate
command with the following code.profiling code
Put the code in the root directory of this repository.
Result:
$ stackprof stackprof-out-1645283785.4565349 ================================== Mode: wall(1000) Samples: 5067 (0.67% miss rate) GC: 1351 (26.66%) ================================== TOTAL (pct) SAMPLES (pct) FRAME 875 (17.3%) 875 (17.3%) (marking) 472 (9.3%) 472 (9.3%) Kernel#class 470 (9.3%) 470 (9.3%) (sweeping) 285 (5.6%) 285 (5.6%) RBS::Namespace#initialize 213 (4.2%) 213 (4.2%) RBS::Substitution#empty? 152 (3.0%) 152 (3.0%) Kernel#hash (snip)
Kernel#class
takes 9.3% of the wallclock time. It's the heaviest method.Benchmarking
Benchmarking Code
before
after
It improves ips from 1.990 to 2.128, 1.069x faster. 🚀
Removing
self.class.hash
is safeIt's safe.
By this change,
hash
method will return the same value between different class objects. It does not break the rule ofhash
andeql?
methods.I guess hash keys classes for one hash object are the same class in many cases, so the collision will occur rarely.
By the way, some
self.class.hash
method calls still remain. For example: lib/rbs/types.rbThese method calls are not the bottleneck. And their implementations are too simple, so if
self.class.hash
is removed they introduces collisions easily. So I didn't remove theself.class.hash
.