This PR improves the performance of super calls. While working on some
Rails optimizations jhawthorn discovered that super calls were slower
than expected.
The changes here do the following:
Adds a check for whether the call frame is not equal to the method
entry iseq. This avoids the rb_obj_is_kind_of check on the next line
which is quite slow. If the current call frame is equal to the method
entry we know we can't have an instance eval, etc.
Changes FL_TEST to FL_TEST_RAW. This is safe because we've
already done the check for T_ICLASS above.
Adds a benchmark for T_ICLASS super calls.
Note: makes a chage for method_entry_cref to use const.
On master the benchmarks showed that super is 1.76x slower. Our
changes improved the performance so that it is now only 1.36x slower.
Benchmark IPS:
Warming up --------------------------------------
super 244.918k i/100ms
method call 383.007k i/100ms
Calculating -------------------------------------
super 2.280M (± 6.7%) i/s - 11.511M in 5.071758s
method call 3.834M (± 4.9%) i/s - 19.150M in 5.008444s
Comparison:
method call: 3833648.3 i/s
super: 2279837.9 i/s - 1.68x (± 0.00) slower
With changes:
Warming up --------------------------------------
super 308.777k i/100ms
method call 375.051k i/100ms
Calculating -------------------------------------
super 2.951M (± 5.4%) i/s - 14.821M in 5.039592s
method call 3.551M (± 4.9%) i/s - 18.002M in 5.081695s
Comparison:
method call: 3551372.7 i/s
super: 2950557.9 i/s - 1.20x (± 0.00) slower
This is the benchmark script used for the benchmark-ips benchmarks:
require"benchmark/ips"classFoodefzuper;enddeftop;endlast_method="top"("A".."M").eachdo|module_name|eval<<-EOM
module #{module_name}
def zuper; super; end
def #{module_name.downcase}#{last_method}
end
end
prepend #{module_name} EOMlast_method=module_name.downcaseendendfoo=Foo.newBenchmark.ipsdo|x|x.report"super"dofoo.zuperendx.report"method call"dofoo.mendx.compare!end
Improve the performance of super
This PR improves the performance of
super
calls. While working on someRails optimizations jhawthorn discovered that
super
calls were slowerthan expected.
The changes here do the following:
entry iseq. This avoids the
rb_obj_is_kind_of
check on the next linewhich is quite slow. If the current call frame is equal to the method
entry we know we can't have an instance eval, etc.
FL_TEST
toFL_TEST_RAW
. This is safe because we'vealready done the check for
T_ICLASS
above.T_ICLASS
super calls.method_entry_cref
to useconst
.On master the benchmarks showed that
super
is 1.76x slower. Ourchanges improved the performance so that it is now only 1.36x slower.
Benchmark IPS:
With changes:
Ruby VM benchmarks also showed an improvement:
Existing
vm_super
benchmark`.New
vm_iclass_super
benchmark:This is the benchmark script used for the benchmark-ips benchmarks:
Co-authored-by: Aaron Patterson [email protected]
Co-authored-by: John Hawthorn [email protected]