m2

indexOf と RegExp の速度比較

単純な特定文字列の存在確認をするのに indexOf と正規表現でどれくらい差があるのかなと思って、次のようなコードを書きました。

(function(){
var a = [], n = 10000;
for (var i = 0; i < n; i++) {
   a.push('item:' + i);
}
var str = a.join('\n');

var s = new Date();
for (var i = 0; i < 3000; i++) {
    //var m = str.indexOf('item:9999');           // (1) indexOf
    //var m = /item:9999/.exec(str);             // (2) 静的な正規表現
    //var m = new RegExp('item:9999').exec(str); // (3) 動的生成の正規表現
    //var m = /item:9999$/.exec(str);             // (4) 正規表現 (3/31 追加)
}
alert(new Date() - s + '(ms) result:' + m);

})()

なかなか面白い結果となりました。
単位は(ms) で、何回かやって大体平均の値です。
2010/6/19 Google Chrome 5.0.375.70 を追加。こちらも Opera 10.52 とおなじくキャシュしている模様。

ケース Opera 10.10 Opera 10.52 Firefox 3.6.2 Google Chrome 4.1.249 Google Chrome 5.0.375.70
(1) indexOf 980 1240 271 214 190
(2) /item:9999/ 1600 3 3510 210 2
(3) new RegExp('item:9999') 1615 385 3600 230 198

それじゃブラウザ別に見ていきましょう。

Opera 10.10

Opera の1世代前のバージョンです。
indexOf が正規表現より速いのは予想通り。数値的にも予想通りですが、indexOf が最新の 10.52 より速いのは驚きでした。

Opera 10.52

Opera の現時点の最新バージョン。
高速な JavaScript エンジンが売りのひとつですが、indexOf が遅く、前のバージョンに負けてます。
(2) の結果は間違いなくキャッシュ。
(3) が本来の正規表現のパフォーマンスだと思われますが indexOf より速いのは驚きでした。

Firefox 3.6.2

現在の Firefox 最新バージョン
indexOf は高速ですがとにかく正規表現おっせーっす。

Google Chrome 4.1.249

なにこれこわい。

  • -

補足

  • (3) で正規表現を new するだけにしてみると、どのブラウザも 10 (ms) 程度でした。とても速いですね。
  • 「存在確認なら exec じゃなくて test だろーが」そうですね。まあでもあんまかわんなかったっすよ?
  • -

3/31 追記

chromeはindexOfで済むならindexOfを使う、という最適化でもしてるのかな。

http://b.hatena.ne.jp/barelo/20100331#bookmark-20426180

あーたぶんビンゴです。今回の趣旨とは違うけど、特定文字列ではなく正規表現でマッチさせてみました。

ケース Opera 10.10 Opera 10.52 Firefox 3.6.2 Google Chrome 4.1.249
(4) /item:9999$/ 1600 3 3600 572

ちょっとだけ身近な存在になりました。