From: Yusuke Endoh Date: 2011-07-09T01:33:29+09:00 Subject: [ruby-dev:44068] [Ruby 1.9 - Feature #5000][Open] skip string creation of when clause Issue #5000 has been reported by Yusuke Endoh. ---------------------------------------- Feature #5000: skip string creation of when clause http://redmine.ruby-lang.org/issues/5000 Author: Yusuke Endoh Status: Open Priority: Normal Assignee: Yusuke Endoh Category: Target version: 1.9.3 遠藤です。 when 節に文字列リテラルをそのまま書くことは結構あると思います。 case str when "foo" when "bar" when "baz" end 現在は when 節の比較を実行するごとに、String オブジェクトが生成 されています。しかし、この場合は毎回同じオブジェクトを返せばいい と思います。最良のケースで、このくらい高速化します。 $ cat t.rb 5000000.times do case nil when "foo" when "bar" when "baz" end end # パッチ前 $ time ./ruby.org t.rb real 0m4.561s user 0m4.488s sys 0m0.004s # パッチ後 $ time ./ruby.new t.rb real 0m2.881s user 0m2.828s sys 0m0.036s when x="foo" や when "foo#{x}" のような場合には最適化しません。 make check も通ったし、ささださんの了解も得ていますので、コミット してやる所存です。反対があればお早めにどうぞ。 diff --git a/compile.c b/compile.c index 01c99b6..53149ca 100644 --- a/compile.c +++ b/compile.c @@ -2362,7 +2362,14 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR *cond_seq, NODE *vals, LABEL *l1, VALUE s special_literals = Qfalse; } - COMPILE(cond_seq, "when cond", val); + if (nd_type(val) == NODE_STR) { + debugp_param("nd_lit", val->nd_lit); + OBJ_FREEZE(val->nd_lit); + ADD_INSN1(cond_seq, nd_line(val), putobject, val->nd_lit); + } + else { + COMPILE(cond_seq, "when cond", val); + } ADD_INSN1(cond_seq, nd_line(val), topn, INT2FIX(1)); ADD_SEND(cond_seq, nd_line(val), ID2SYM(idEqq), INT2FIX(1)); ADD_INSNL(cond_seq, nd_line(val), branchif, l1); -- Yusuke Endoh -- http://redmine.ruby-lang.org