/文字列/g

Narcissus の正規表現: Days on the Moon

なぜか SpiderMonkey では前者に対して後者のほうが約 60% も遅く

ふむむ?

n = arguments[0];
for($ = [], i = 0; (l = readline()) != null;) $[i++] = l;
$ = $.join('\n');
for each(r in [
  /"(?:\\.|[^\\\"])*"/g,         // original
  /"(?:[^\\\"]|\\.)*"/g,         // should be faster than above...
  /"[^\\\"]*(?:\\.[^\\\"]*)*"/g, // loop-extracted
]){
  for(t = new Date, i = n; i--;) $.match(r);
  print(r, '\n =>', (new Date - t) / n, '[ms]\n');
}
$ js regex_bench.js 100 < jquery-1.2.5.js
/"(?:\\.|[^\\\"])*"/g
 => 29.33 [ms]

/"(?:[^\\\"]|\\.)*"/g
 => 37.6 [ms]

/"[^\\\"]*(?:\\.[^\\\"]*)*"/g
 => 16.38 [ms]

ホントだ。やはりSpiderMonkeyはオカシイ。

JScript でも両者の実行時間はほぼ同じ

n = WSH.arguments(0);
$ = WSH.stdIn.readAll();
for(k in rs = [
  /"(?:\\.|[^\\\"])*"/g,         // original
  /"(?:[^\\\"]|\\.)*"/g,         // should be faster than above...
  /"[^\\\"]*(?:\\.[^\\\"]*)*"/g, // loop-extracted
]){
  for(t = new Date, i = n; i--;) $.match(rs[k]);
  WSH.echo(rs[k], '\n =>', (new Date - t) / n, '[ms]\n');
}
>cscript //nologo regex_bench_m$.js 100 < jquery-1.2.5.js
/"(?:\\.|[^\\\"])*"/g
 => 90.79 [ms]

/"(?:[^\\\"]|\\.)*"/g
 => 88.77 [ms]

/"[^\\\"]*(?:\\.[^\\\"]*)*"/g
 => 2.97 [ms]

確かに。
しかしそれよりも三つ目の異様な速さ(と前の二つの遅さ)が気になる。
よほど「 | 」の処理が重いんだろうか。

結論

ちゃんとループ展開しましょう。