Rubyの話です。
↓の記事を読んでいたら実行速度の話が出てきたので気になってシュッと調べてみました。 moneyforward.com
動作環境: Ruby 2.5.1
単一の文字列とのマッチ
正規表現は、あるパターンに従う文字列の集まりを指したいときには便利ですが、単一の文字列とのマッチに正規表現を使うのはやめましょう。文字列を使うべきです。実行速度がだいぶ違います。
比較してみた。文字列を10,000回splitするのを100回やって処理時間の平均値を出す。
irb(main):001:0> str = 'abcdefgh' => "abcdefgh" irb(main):002:0> 100.times.map{ Benchmark.realtime{ 10000.times{ str.split(/e/) } } }.sum / 100 => 0.009860930000431836 irb(main):003:0> 100.times.map{ Benchmark.realtime{ 10000.times{ str.split('e') } } }.sum / 100 => 0.003988147991476581
文字列を使ったほうが2倍くらい速い
パターンマッチするか否かの真偽値
=~
はマッチに成功した場合にただのtrue
ではなくマッチの位置を返します。制御構造の条件や論理演算で使っても問題になることはありませんが、これは欲しい情報に対して過多な情報で、そのために実行効率を落としています。真偽値を返すString#match?
やRegexp#match?
に置き換えるだけで数倍速くなります。
比較してみた。パターンマッチの真偽値を10,000回出すのを、100回やって処理速度の平均値を出す。
irb(main):001:0> str = 'abcdefgh' => "abcdefgh" irb(main):002:0> 100.times.map{ Benchmark.realtime{ 10000.times{ str =~ /e/ } } }.sum / 100 => 0.002607569007668644 irb(main):003:0> 100.times.map{ Benchmark.realtime{ 10000.times{ str.match?(/e/) } } }.sum / 100 => 0.0013666660047601908
String#match?
を使ったほうが2倍くらい速い
完全一致
完全一致の場合は
=~
(もしくはmatch?
)で比較するまでもなく、文字列にとって最も基本的な関係演算である==
を使えばよいのです。
比較してみた。完全一致の真偽値を10,000回出すのを、100回やって処理速度の平均値を出す。
irb(main):001:0> str = 'abcdefgh' => "abcdefgh" irb(main):002:0> 100.times.map{ Benchmark.realtime{ 10000.times{ str =~ /\Aabcdefgh\z/ } } }.sum / 100 => 0.0026517410040833057 irb(main):003:0> 100.times.map{ Benchmark.realtime{ 10000.times{ str == 'abcdefgh' } } }.sum / 100 => 0.000976948984898627
==
を使ったほうが3倍くらい速い
まとめ
記事内には他にも比較できそうなものがありましたが、今回はこの辺で。実際に数字を出してみると「ほぉ〜」となりますね。
ではまた。