以下の 3 つについて比較します。
-
Regexp#=~
: 文字列中のマッチする位置を整数で返す。しなければnil
。 -
Regexp#===
マッチするかどうかをtrue
orfalse
で返す。 -
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#=~
と特に違いませんでした。