From: UENO Katsuhiro Date: 2003-03-14T00:22:50+09:00 Subject: [ruby-list:37301] Re: 両方の式とも常に評価する論理和・論理積 うえのです。 On Thu, 13 Mar 2003 23:29:13 +0900 nobu.nakada@nifty.ne.jp wrote: > > > なぜか、「ローカル変数を使う」が最速です。 > > > 何回かやってみると、「正規表現をまとめる」が最速のこともありますが、 > > > まさか「ローカル変数を使う」が「戻り値を考慮しない」よりも > > > 速いとは思ってみませんでした。 > > > (ベンチマークの取り方が間違っているんでしょうか?) > > > > おそらく、$~ を格納する場所をパース時に作る(ローカル変数を使用する方法) > > か、実行時に作るか(正規表現を一つにまとめる)で差が出ているのでは > > ないでしょうか。 > > Perlと違って、$_,$~は常に用意されています。どちらかというと正規 > 表現のバックトラック関係のような気がしますが、はっきりしたこと > は。 $_, $~ が用意されるのはローカル変数のスコープが生成されているとき (= メソッド内にローカル変数があるとき) だけではないですか? rb_backref_set から special_local_set が呼び出されるのが遅くなる 原因ではないかと推測したんですが…。 例えばこんなスクリプトを require 'benchmark' class String def foo gsub!(/\A\s+/,'') gsub!(/\s+\z/,'') end def foo2 tmp1 = gsub!(/\A\s+/,'') tmp2 = gsub!(/\s+\z/,'') end end Test = [ "abc", "abc \r\n", "\n\t abc", "\n\t abc \r\n" ] Benchmark.bm(12) { |x| [:foo].each { # ここを :foo2 に書き換えてもう一度実行、比較 GC.disable x.report(m.to_s) { 5000.times { Test.each { |i| i.dup.send m } } } } } 1.6.8 で動かしてプロファイルを取ってみると、foo2 よりも foo の ほうが top_local_setup, top_local_init, local_cnt の3関数がそれぞれ ちょうど2万回 (= Test.size * 5000) ずつ多く呼び出されています。 ruby_xmalloc が呼ばれる回数も foo のほうが6万回多くなりました。 ローカル変数を使わないほうが遅い理由はこれではないかと思うのですが、 如何でしょう。 -- ---- - - - -- - うえの かつひろ