[#37249] ruby 1.8でのCGI#[]の挙動 — 堀川 久 <vzw00011@...>

こんにちは。

14 messages 2003/03/09

[#37283] 両方の式とも常に評価する論理和・論理積 — Shinya Kawaji <kawaji@...>

かわじ、です

17 messages 2003/03/13

[#37324] optparse は使いやすいですか? — 成島 寛則 <narushima@...>

こんにちは。Narushima Hironori と申します。

13 messages 2003/03/15

[#37370] Secure「ではない」script の書き方 — satoru takahashi <hisai@...>

高橋聡@JFプロジェクトで翻訳しています、です

50 messages 2003/03/20
[#37381] Re: Secure「ではない」script の書き方 — satoru takahashi <hisai@...> 2003/03/20

高橋聡です

[#37382] Re: Secure「ではない」script の書き方 — matz@... (Yukihiro Matsumoto) 2003/03/20

まつもと ゆきひろです

[#37405] Re: Secure「ではない」script の書き方 — Taku Nakajima <tnakajima@...> 2003/03/24

[#37407] Re: Secure「ではない」script の書き方 — matz@... (Yukihiro Matsumoto) 2003/03/24

まつもと ゆきひろです

[#37414] Re: Secure「ではない」script の書き方 — Taku Nakajima <tnakajima@...> 2003/03/25

[#37415] Re: Secure「ではない」script の書き方 — matz@... (Yukihiro Matsumoto) 2003/03/25

まつもと ゆきひろです

[#37417] Re: Secure「ではない」script の書き方 — Taku Nakajima <tnakajima@...> 2003/03/25

[#37421] Tmpfile.newがデフォルトで/tmpを利用すること — Tadatoshi Kamimura <kamimura.tadatoshi@...>

上村と申します。はじめまして。

35 messages 2003/03/26
[#37422] Re: Tmpfile.newがデフォルトで/tmpを利用すること — WATANABE Hirofumi <eban@...> 2003/03/26

わたなべです。

[#37467] Re: Tmpfile.newがデフォルトで/tmpを利用すること — Tadatoshi Kamimura <kamimura.tadatoshi@...> 2003/03/31

上村です

[#37468] Re: Tmpfile.newがデフォルトで/tmpを利用すること — "Akinori MUSHA" <knu@...> 2003/03/31

At Mon, 31 Mar 2003 09:51:27 +0900,

[#37470] Re: Tmpfile.newがデフォルトで/tmpを利用すること — Tadatoshi Kamimura <kamimura.tadatoshi@...> 2003/03/31

上村です。

[#37472] Re: Tmpfile.newがデフォルトで/tmpを利用すること — "Akinori MUSHA" <knu@...> 2003/03/31

 なるほど、 $SAFE=1 のところをすっぱり読み飛ばしてました。

[#37479] Re: Tmpfile.new がデフォルトで/tmpを利用すること — siena@... (Siena. / SHINAGAWA, Norihide) 2003/03/31

Siena. です。

[#37480] Re: Tmpfile.new がデフォルトで/tmpを利用すること — siena@... (Siena. / SHINAGAWA, Norihide) 2003/03/31

Siena. です。

[#37483] Re: Tmpfile.newがデフォルトで/tmpを利用すること — nobu.nakada@... 2003/04/01

なかだです。

[#37493] Re: Tmpfile.newがデフォルトで/tmpを利用すること — TAKAISHI Hayato <rio-t@...> 2003/04/02

こんにちは、高石です。

[#37496] Re: Tmpfile.new がデフォルトで/tmpを利用すること — siena@... (Siena. / SHINAGAWA, Norihide) 2003/04/03

Siena. です。

[#37499] Re: Tmpfile.new がデフォルトで/tmpを利用すること — matz@... (Yukihiro Matsumoto) 2003/04/03

まつもと ゆきひろです

[#37500] Re: Tmpfile.new がデフォルトで/tmpを利用すること — "U.Nakamura" <usa@...> 2003/04/03

こんにちは、なかむら(う)です。

[ruby-list:37297] Re: 両方の式とも常に評価する論理和・論理積

From: Shinya Kawaji <kawaji@...>
Date: 2003-03-13 07:16:08 UTC
List: ruby-list #37297
かわじ、です。


> > class String
> >   def s_strip!
> >     tmp1 = gsub!(/\A\s+/,'')
> >     tmp2 = gsub!(/\s+\z/,'')
> >     (tmp1 or tmp2) ? self : nil
> >   end
> > end
> > 
> > とローカル変数を使うか、
> 
> これが分かり易くて良いのではありませんかね?
[snip]
> 
> スクリプトを記述する際の文字数を減らすとか、実行速度を最大にするとかで
> あればともかく、誰が読んでも意図が伝わる(伝わり易い)書き方が好ましいん
> じゃないかなぁ、と個人的には思います。

ありがとうございます。元々は、もっと短くなる記法があれば、それが結局、
もっと速くなることにつながると思っていたのですが、ちょっと違うようです。


わたなべさんの「正規表現を一つにまとめる」も含めて、ベンチマークを
取ってみました。(ありがとうございます>わたなべさん)

(CPU: celeron400MHz, Memory: 64MBくらい)
$ ruby -v
ruby 1.6.7 (2002-03-01) [i386-openbsd3.1]

$ cat tmp.rb
require 'benchmark'

class String
  # 正規表現を一つにまとめる
  def s_strip1!
    gsub!(/\A\s+|\s+\z/,'')
  end

  # 戻り値を考慮しない
  def s_strip2!
    gsub!(/\A\s+/,'')
    gsub!(/\s+\z/,'')
  end

  # ローカル変数を使用
  def s_strip3!
    tmp1 = gsub!(/\A\s+/,'')
    tmp2 = gsub!(/\s+\z/,'')
    (tmp1 or tmp2) ? self : nil
  end

  # 補助関数を使用
  def s_strip4!
    __get_result(
      gsub!(/\A\s+/,''),
      gsub!(/\s+\z/,'')
    )
  end
  def __get_result(*args)
    args.compact.empty? ? nil : self
  end

  # !!を使用
  def s_strip5!
    (!!gsub!(/\A\s+/,'') | !!gsub!(/\s+\z/,'')) ? self : nil
  end

  # findを使用
  def s_strip6!
    [gsub!(/\A\s+/,''), gsub!(/\s+\z/,'')].find{|x| x}
  end

  # nil?を使用
  def s_strip7!
    gsub!(/\A\s+/,'').nil? & gsub!(/\s+\z/,'').nil? ? nil : self
  end
end

TIMES = 50_000
TEXT  = [
  "abc",
  "abc \r\n",
  "\n\t abc",
  "\n\t abc \r\n",
]
RESULT = 'abc'


# 戻り値をチェック
1.upto(7){|i|
  TEXT.each_with_index{|text,j|
    source = text.dup
    result = source.send("s_strip#{i}!")
    raise unless source == RESULT
    unless i == 2 # 「戻り値を考慮しない」を除く
      if j == 0 # 変更無しは nil を返す
        raise unless result.nil?
      else
        raise unless result == RESULT
      end
    end
  }
}

Benchmark.bm(12){|x|
  1.upto(7){|i|
    x.report("s_strip#{i}!:"){
      TIMES.downto(1){
        TEXT.each{|text|
          text.dup.send("s_strip#{i}!")
        }
      }
    }
  }
}

$ ruby tmp.rb
                  user     system      total        real
s_strip1!:   11.440000   0.000000  11.440000 ( 11.438658)
s_strip2!:   12.300000   0.000000  12.300000 ( 12.347814)
s_strip3!:   11.250000   0.000000  11.250000 ( 11.250715)
s_strip4!:   15.240000   0.000000  15.240000 ( 15.260732)
s_strip5!:   12.700000   0.000000  12.700000 ( 12.697829)
s_strip6!:   15.380000   0.000000  15.380000 ( 15.394424)
s_strip7!:   12.880000   0.000000  12.880000 ( 12.902847)


なぜか、「ローカル変数を使う」が最速です。
何回かやってみると、「正規表現をまとめる」が最速のこともありますが、
まさか「ローカル変数を使う」が「戻り値を考慮しない」よりも
速いとは思ってみませんでした。
(ベンチマークの取り方が間違っているんでしょうか?)


試しに、Ruby1.8.0 でもやってみました。
(アーキテクチャは上記と違って、PentiumIIIかIVの1.0GHzくらい)

$ ruby -v
ruby 1.8.0 (2003-02-16) [i686-linux]

$ ruby tmp.rb
                  user     system      total        real
s_strip1!:    7.840000   0.010000   7.850000 (  7.847412)
s_strip2!:    8.890000   0.000000   8.890000 (  8.887431)
s_strip3!:    7.950000   0.000000   7.950000 (  7.957038)
s_strip4!:   10.730000   0.010000  10.740000 ( 10.730664)
s_strip5!:    9.090000   0.020000   9.110000 (  9.112299)
s_strip6!:   11.970000   0.000000  11.970000 ( 11.968175)
s_strip7!:    9.320000   0.010000   9.330000 (  9.335643)

こちらは、「正規表現をまとめる」「ローカル変数を使う」の順です。


あくまでも現在の実装に限った話ですし、最速こそが全てではないのですが、
自分の思いこみで「これが速いはずだ」と思っていたのが、全然違うと
いうことに気付きました。

ローカル変数を使う方法は、ソースの変更の際に、例えば内部の破壊的メソッド
をもう一つ増やしたら、その結果を記録するローカル変数も増やさないと
いけないのが嫌だなあ、と思っていたのですが、どれもそれほど速さに違いは
ないですし、読みやすさやメンテナンスのしやすさの兼ね合わせをもうちょっと
考えることにします。

--
Shinya Kawaji



In This Thread