summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2019-11-29 03:02:44 +0900
committerKoichi Sasada <ko1@atdot.net>2019-11-29 03:11:04 +0900
commitdd723771c118da71aa58bb74537cacaec425542a (patch)
tree435dd65e4d2e4d6a329c511ab1640cf165dff394 /test
parentb5fbefbf2c14742f6d46ecdf3ce712062dfb1d0a (diff)
fastpath for ivar read of FL_EXIVAR objects.
vm_getivar() provides fastpath for T_OBJECT by caching an index of ivar. This patch also provides fastpath for FL_EXIVAR objects. FL_EXIVAR objects have an each ivar array and index can be cached as T_OBJECT. To access this ivar array, generic_iv_tbl is exposed by rb_ivar_generic_ivtbl() (declared in variable.h which is newly introduced). Benchmark script: Benchmark.driver(repeat_count: 3){|x| x.executable name: 'clean', command: %w'../clean/miniruby' x.executable name: 'trunk', command: %w'./miniruby' objs = [Object.new, 'str', {a: 1, b: 2}, [1, 2]] objs.each.with_index{|obj, i| rep = obj.inspect rep = 'Object.new' if /\#/ =~ rep x.prelude str = %Q{ v#{i} = #{rep} def v#{i}.foo @iv # ivar access method (attr_reader) end v#{i}.instance_variable_set(:@iv, :iv) } puts str x.report %Q{ v#{i}.foo } } } Result: v0.foo # T_OBJECT clean: 85387141.8 i/s trunk: 85249373.6 i/s - 1.00x slower v1.foo # T_STRING trunk: 57894407.5 i/s clean: 39957178.6 i/s - 1.45x slower v2.foo # T_HASH trunk: 56629413.2 i/s clean: 39227088.9 i/s - 1.44x slower v3.foo # T_ARRAY trunk: 55797530.2 i/s clean: 38263572.9 i/s - 1.46x slower
Diffstat (limited to 'test')
-rw-r--r--test/ruby/test_variable.rb19
1 files changed, 19 insertions, 0 deletions
diff --git a/test/ruby/test_variable.rb b/test/ruby/test_variable.rb
index f14b4019df..0772066143 100644
--- a/test/ruby/test_variable.rb
+++ b/test/ruby/test_variable.rb
@@ -178,6 +178,25 @@ class TestVariable < Test::Unit::TestCase
end
end
+ class ExIvar < Hash
+ def initialize
+ @a = 1
+ @b = 2
+ @c = 3
+ end
+
+ def ivars
+ [@a, @b, @c]
+ end
+ end
+
+ def test_external_ivars
+ 3.times{
+ # check inline cache for external ivar access
+ assert_equal [1, 2, 3], ExIvar.new.ivars
+ }
+ end
+
def test_local_variables_with_kwarg
bug11674 = '[ruby-core:71437] [Bug #11674]'
v = with_kwargs_11(v1:1,v2:2,v3:3,v4:4,v5:5,v6:6,v7:7,v8:8,v9:9,v10:10,v11:11)