LoginSignup
2
2

More than 5 years have passed since last update.

Regexp によるマッチングのベンチマーク

Last updated at Posted at 2016-02-26

以下の 3 つについて比較します。

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

2
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2