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)正規表現内で文字列展開すると極端に遅くなる。
そう言えば、
のブックマークコメントで、
コストの面で正規表現は論外だと思う。
って書いたけど、ほんのちょっと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のほうがちょっと速い。