以下の 3 つについて比較します。
-
Regexp#=~: 文字列中のマッチする位置を整数で返す。しなければnil。 -
Regexp#===マッチするかどうかをtrueorfalseで返す。 -
Regexp#match: マッチしたらMatchDataオブジェクトを返す。しなければnil。
もちろん、これらはいずれも返す値が違うが、例えば以下のようにマッチするかどうかだけをチェックしたいときにどれを使うと速いのかだけ考える。
do_hoge if re =~ str
ベンチマークコード
bench.rb
require 'benchmark'
N = 10_000_000
REGEXP = /Chrome/
STRING = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36'
Benchmark.bm do |b|
b.report('Regexp#=~ ') do
N.times { REGEXP =~ STRING }
end
b.report('Regexp#=== ') do
N.times { REGEXP === STRING }
end
b.report('Regexp#match') do
N.times { REGEXP.match STRING }
end
end
実行結果
$ ruby regexp.rb
user system total real
Regexp#=~ 2.670000 0.020000 2.690000 ( 2.696319)
Regexp#=== 2.660000 0.020000 2.680000 ( 2.699713)
Regexp#match 9.460000 0.270000 9.730000 ( 9.837536)
まとめ
Regexp#=~ と Regexp#=== の差は誤差の範囲。
繰り返し実行しているとどっちが勝つケースもあった。
個人的には Regexp#=~ の方が「正規表現マッチングしてるんだ」という意図性がわかりやすいので好み。
(=== は JavaScript や PHP だと同一性のチェック等に使われているから、というのもある)
しかし Regexp#match は有意に遅いので、MatchData オブジェクトが必要ない限りは使わないほうが良さそう。
やはり MatchData オブジェクトの生成コストによる差だと思われる。
ひとこと
個人的には String#=~ の方が読みやすくて好き。
ちなみにベンチマーク的には Regexp#=~ と特に違いませんでした。