読者です 読者をやめる 読者になる 読者になる

固定の文字列が先頭にあるかを調べる場合、String#indexより正規表現の方が早いらしい。

require 'benchmark'

n = 1_000_000

str  = ('a'..'z').to_a.to_s
str += ('A'..'Z').to_a.to_s
str = str * 100

x = "abc"

Benchmark.bm do |x|
  x.report("regexp")  { n.times { str =~ /^abc/         ? "t" : "f" } }
  x.report("index")   { n.times { str.index("abc") == 0 ? "t" : "f" } }
  x.report("include") { n.times { str.include?("abc")   ? "t" : "f" } }
  x.report("regexp var") { n.times { str =~ /^#{x}/     ? "t" : "f" } }
end
$ ruby /tmp.rb
      user     system      total        real
regexp  1.047000   0.000000   1.047000 (  1.043000)
index  1.281000   0.000000   1.281000 (  1.278000)
include  0.985000   0.000000   0.985000 (  1.099000)
regexp var 28.140000   0.000000  28.140000 ( 28.836000)

正規表現内で文字列展開すると極端に遅くなる。


そう言えば、

のブックマークコメントで、

コストの面で正規表現は論外だと思う。

http://b.hatena.ne.jp/entry/http://q.hatena.ne.jp/1207585413

って書いたけど、ほんのちょっとinclude?が速い程度で論外では全然なかった。

(追記) タイトルの件は嘘でした。少なくとも環境による。上のはWindows(Cygwin)で実行していた(はず)。

OSXだと、

$ ruby tmp.rb
      user     system      total        real
regexp  0.880000   0.000000   0.880000 (  0.893239)
index  0.620000   0.010000   0.630000 (  0.627702)
include  0.470000   0.000000   0.470000 (  0.473958)
regexp var  7.170000   0.030000   7.200000 (  7.307936)

Linuxだと

$ ruby tmp.rb
      user     system      total        real
regexp  0.990000   0.000000   0.990000 (  0.992646)
index  0.920000   0.010000   0.930000 (  0.934713)
include  0.700000   0.000000   0.700000 (  0.696367)
regexp var  9.850000   0.140000   9.990000 ( 10.111677)

何度やってもindexのほうがちょっと速い。