togetter 正規表現が構文として必要かどうかという話から
古い話だが、だいたいこんな感じのことが書いてある
正規表現リテラルがないと、正規表現を適用する度ごとに、毎回正規表現をコンパイルするコードを書きがちです。これは、実行速度を大幅に悪化させます。正規表現リテラルがあれば、正規表現を言語処理系側でコンパイルして使い回すことができるので、実行速度が向上します。
http://blog.kazuhooku.com/2013/12/blog-post.html より。強調部原文ママ
本当だろうか?
正規表現リテラルは、ほとんど単に、シュガーシンタックスとして実装されてるのではないだろうか??
実験してみた
(追記:デバッグコンソールでブラウザ実行/静的jsでブラウザ実行/node.jsで実行)
var str = "abfdfaerajofajo39u82ini98c9a434428jm3nicaa3e"
// ■ループ内で Newする
var t = Date.now();
for(var i=0; i<1000000; i++){
(new RegExp("[A-ZA-Zア-ロア-ロあ-れ]{1}(.{0,2})?[\--.]?[0-90-9]{2}[\--.]?[abab]")).test(str);
}
console.log(Date.now() - t);
// 33.584秒/27.6213秒/0.262秒
// ■ループ内で リテラル:Newより早いはず
var t = Date.now();
var str = "abfdfaerajofajo39u82ini98c9a434428jm3nicaa3e"
for(var i=0; i<1000000; i++){
/[A-ZA-Zア-ロア-ロあ-れ]{1}(.{0,2})?[\--.]?[0-90-9]{2}[\--.]?[abab]/.test(str);
}
console.log(Date.now() - t);
// 32.345秒/0.762秒/0.071秒
// ■1回だけ Newする
var t = Date.now();
var rx = new RegExp("[A-ZA-Zア-ロア-ロあ-れ]{1}(.{0,2})?[\--.]?[0-90-9]{2}[\--.]?[abab]");
for(var i=0; i<1000000; i++){
rx.test(str);
}
console.log(Date.now() - t);
// 5.406秒/0.682秒/0.065秒
// ■1回だけ リテラル:1回だけのNewと同じ速度のはず
var t = Date.now();
var rx = /[A-ZA-Zア-ロア-ロあ-れ]{1}(.{0,2})?[\--.]?[0-90-9]{2}[\--.]?[abab]/;
var str = "abfdfaerajofajo39u82ini98c9a434428jm3nicaa3e"
for(var i=0; i<1000000; i++){
rx.test(str);
}
console.log(Date.now() - t);
// 5.297秒/0.622秒/0.067秒
あ、あれー!?
全然ダメじゃん!
追記: デバッグコンソールダメじゃん! あとループ内での正規表現リテラルは早い。
27.6213秒 -> 0.762秒 とか、 0.262秒 -> 0.071秒 に減少する。ループ内でNewすることはない
結論
すくなくともjavascriptにおいては、 正規表現リテラルをループ内で使っても速度は変わらない みたいです。
(予想外だったので何回か試したけど、ほぼ同じ結果です)
「正規表現リテラルを使えば早くなる!」 とか言う人は笑ってあげましょう。
**正規表現リテラルは早い!**です
やっぱりループ内で百万回Newするのと比べて正規表現リテラルは10-100倍早いと言えそうです。
また、正規表現リテラルの速度は1回だけNewするのとほぼ等しいです。ただ、厳密には0.1-0.001秒くらい遅い。
あと、デバッグコンソールを使うと最適化が無効になる事もわかりました。