From Ruby 3.0, refined method invocations are slow because
resolved methods are not cached by inline cache because of
conservertive strategy. However, using clears all caches
so that it seems safe to cache resolved method entries.
This patch caches resolved method entries in inline cache
and clear all of inline method caches when using is called.
# without refinementsclassCdeffoo=:CendN=1_000_000obj=C.newrequire'benchmark'Benchmark.bm{|x|x.report{N.times{obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;}}}_END__usersystemtotalrealmaster0.3628590.0025440.365403(0.365424)modified0.3572510.0000000.357251(0.357258)
# with refinment but without usingclassCdeffoo=:CendmoduleRrefineCdodeffoo=:RendendN=1_000_000obj=C.newrequire'benchmark'Benchmark.bm{|x|x.report{N.times{obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;}}}__END__
user system total real
master 0.957182 0.000000 0.957182 ( 0.957212)
modified 0.359228 0.000000 0.359228 ( 0.359238)
# with usingclassCdeffoo=:CendmoduleRrefineCdodeffoo=:RendendN=1_000_000usingRobj=C.newrequire'benchmark'Benchmark.bm{|x|x.report{N.times{obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;obj.foo;}}}
Related issues
Bug #18572: Performance regression when invoking refined methods
use inline cache for refinements
From Ruby 3.0, refined method invocations are slow because
resolved methods are not cached by inline cache because of
conservertive strategy. However,
using
clears all cachesso that it seems safe to cache resolved method entries.
This patch caches resolved method entries in inline cache
and clear all of inline method caches when
using
is called.fix [Bug #18572]