mirror of
https://github.com/ruby/ruby.git
synced 2025-08-25 14:05:02 +02:00
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 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. fix [Bug #18572] ```ruby # without refinements class C def foo = :C end N = 1_000_000 obj = C.new require '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.362859 0.002544 0.365403 ( 0.365424) modified 0.357251 0.000000 0.357251 ( 0.357258) ``` ```ruby # with refinment but without using class C def foo = :C end module R refine C do def foo = :R end end N = 1_000_000 obj = C.new require '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) ``` ```ruby # with using class C def foo = :C end module R refine C do def foo = :R end end N = 1_000_000 using R obj = C.new require '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; }} }
This commit is contained in:
parent
280419d0e0
commit
cfd7729ce7
Notes:
git
2023-07-31 08:14:03 +00:00
7 changed files with 58 additions and 19 deletions
|
@ -2626,6 +2626,24 @@ class TestRefinement < Test::Unit::TestCase
|
|||
assert_equal([], Refinement.used_modules)
|
||||
end
|
||||
|
||||
def test_inlinecache
|
||||
assert_separately([], <<-"end;")
|
||||
module R
|
||||
refine String do
|
||||
def to_s = :R
|
||||
end
|
||||
end
|
||||
|
||||
2.times{|i|
|
||||
s = ''.to_s
|
||||
assert_equal '', s if i == 0
|
||||
assert_equal :R, s if i == 1
|
||||
using R if i == 0
|
||||
assert_equal :R, ''.to_s
|
||||
}
|
||||
end;
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def eval_using(mod, s)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue