From: Hajime Hoshi Date: 2008-12-04T09:48:10+09:00 Subject: [ruby-dev:37267] Re: [Feature #819] Caching Symbol#to_proc 星と申します。 動作確認はしていないのですが、 sym_proc_cache の生成直後は長さ (len) 0 の配列なので sym_proc_cache の要素の proc オブジェクトは GC に回収されてしまう恐れがあるのではないでしょうか。 2008/12/3 Shumpei Akai : > Feature #819: Caching Symbol#to_proc > http://redmine.ruby-lang.org/issues/show/819 > > 起票者: Shumpei Akai > ステータス: Open, 優先度: Normal > > Symbol#to_proc で毎回オブジェクトを生成するのは無駄な気がするので, > いくつかキャッシュしてはどうでしょうか. > > require 'benchmark' > N=10000 > syms_miss=(1..500).map{|i|"a#{i}".to_sym}syms_hit=[:a]*500 > Benchmark.bm do|r| > r.report("miss"){N.times{syms_miss.each{|x|x.to_proc}}} > r.report(" hit"){N.times{syms_hit.each{|x|x.to_proc}}} > end > > 上のようなベンチマークを取ると,次のようになります. > % ruby_trunk -v > ruby 1.9.1 (2008-12-03 patchlevel 5000 revision 20460) [x86_64-linux] > > キャッシュなし > user system total real > miss 9.060000 0.040000 9.100000 ( 9.092981) > hit 9.070000 0.050000 9.120000 ( 9.114511) > キャッシュあり > user system total real > miss 9.260000 0.020000 9.280000 ( 9.282089) > hit 0.750000 0.000000 0.750000 ( 0.757002) > > 以下パッチです > > Index: string.c > =================================================================== > --- string.c (リビジョン 20465) > +++ string.c (作業コピー) > @@ -6912,13 +6912,37 @@ > * (1..3).collect(&:to_s) #=> ["1", "2", "3"] > */ > > +static VALUE sym_proc_cache=Qfalse; > +#define SYM_PROC_CACHE_SIZE 64 > static VALUE > sym_to_proc(VALUE sym) > { > - return rb_proc_new(sym_call, (VALUE)SYM2ID(sym)); > -} > + VALUE proc; > + ID id; > + long sym_index,proc_index; > + VALUE *aryp; > > > + if(!sym_proc_cache){ > + rb_global_variable(&sym_proc_cache); > + sym_proc_cache = rb_ary_new2(SYM_PROC_CACHE_SIZE * 2); > + } > + > + id=SYM2ID(sym); > + sym_index= (id % SYM_PROC_CACHE_SIZE) << 1; > + proc_index = sym_index | 1; > + > + aryp=RARRAY_PTR(sym_proc_cache); > + if(aryp[sym_index]==sym){ > + return aryp[proc_index]; > + }else{ > + proc = rb_proc_new(sym_call, (VALUE)id); > + aryp[sym_index]=sym; > + aryp[proc_index]=proc; > + return proc; > + } > +} > + > static VALUE > sym_succ(VALUE sym) > > > ---------------------------------------- > http://redmine.ruby-lang.org > > -- Hajime Hoshi