mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	 dd723771c1
			
		
	
	
		dd723771c1
		
	
	
	
	
		
			
			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
		
	
			
		
			
				
	
	
		
			9 lines
		
	
	
	
		
			139 B
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			9 lines
		
	
	
	
		
			139 B
		
	
	
	
		
			C
		
	
	
	
	
	
| 
 | |
| /* per-object */
 | |
| 
 | |
| struct gen_ivtbl {
 | |
|     uint32_t numiv;
 | |
|     VALUE ivptr[FLEX_ARY_LEN];
 | |
| };
 | |
| 
 | |
| struct st_table *rb_ivar_generic_ivtbl(void);
 |