すがブロ

sugamasaoのhatenablogだよ

scan と正規表現のグループ化

どちらがパフォーマンスが良いのか

正規表現のグループ化を行って、 $1 等で値を取得する場合と scan メソッドを使って値を取得するのはどちらが高速なのだろうか。
名前からすると scan メソッドの方が高速な気がするが。。。

実測

以下のようなメソッドを作成してみた。

  1 def reg_test(str)
  2   if str =~ /\d+([a-z])\d+([a-z])/
  3     #puts $1
  4     #puts $2
  5   end
  6 end
  7 
  8 def scan_test(str)
  9   str.scan(/\d+([a-z])\d+([a-z])/) do |m|
 10     #puts m[0]
 11     #puts m[1]
 12   end
 13 end
 14 
 15 str = "123a456b789"
 16 0.upto(10000) { |n|
 17   reg_test str
 18 #  scan_test str
 19 }

reg_test が正規表現の計測のためのメソッドで。 scan_test が scan メソッド測定用。
測定時には 17行目と18行目のコメントアウトを入れ替えて実行したよ。
なるべく、差異が無いようにしたつもりだけれど、これじゃ比較になってないよ! 等があれば教えてください。

結果

各メソッドを3回実行した結果

reg_test

sugamasao% time ruby ./scaner_regexp.rb
ruby ./scaner_regexp.rb 0.03s user 0.00s system 93% cpu 0.037 total
sugamasao% time ruby ./scaner_regexp.rb
ruby ./scaner_regexp.rb 0.03s user 0.00s system 95% cpu 0.032 total
sugamasao% time ruby ./scaner_regexp.rb
ruby ./scaner_regexp.rb 0.02s user 0.00s system 63% cpu 0.044 total

平均 0.03s

scan_test

sugamasao% time ruby ./scaner_regexp.rb
ruby ./scaner_regexp.rb 0.06s user 0.00s system 96% cpu 0.065 total
sugamasao% time ruby ./scaner_regexp.rb
ruby ./scaner_regexp.rb 0.06s user 0.00s system 95% cpu 0.065 total
sugamasao% time ruby ./scaner_regexp.rb
ruby ./scaner_regexp.rb 0.06s user 0.00s system 96% cpu 0.066 total

平均 0.06s

結論

正規表現によるグルーピングの方が高速である
scan の方が早そうな気がしていたんだけどなー。使い方が悪いのだろうか。。。