JavaScriptでマッチ文字列を全置換するにはどうするのが速い?

JavaScriptのStringオブジェクトの文字列置換メソッドであるreplaceは最初にマッチした文字列しか置換しません.replaceAllのようなメソッドも用意されていません.
※str.replace(pattern, replacement, ‘g’)のようにgオプションを指定することによって全置換できるのはFirefoxのみのようです

JavaScriptで全置換する方法として、よく次の2つの方法が挙げられます.

  1. 検索文字列を正規表現にしてグローバルマッチによる置換
    var value = 'Hello World';
    value.replace(/o/g, '*');
    
  2. 検索文字列でsplitして置換文字列でjoinする
    var value = 'Hello World';
    value.split('o').join('*');
    

ふむふむ.っで,どっちが良いの?
どちらでも目的が達成できるのであれば,どうせなら高速な方を採用したいもの.
多くの言語では正規表現を使うと遅いので,正規表現を使わなくてもよいものは使わないのが鉄則.
となると2が有力か?いや,でもsplitしてjoinってどうなの??

そんなわけでどちらが良いのか検証してみました.

– 追記 2014-03-01 –
このご時世、jsPerf という便利なサービスがあるのでそちらでもざっくり比較してみました。
http://jsperf.com/replace-global-vs-split-join
——————–

検証コード

var str1 = '"hoge"', str2 = '"hoge" "fuga" "foo" "bar"';

globalmatch(str1); // (1)
splitjoin(str1);   // (2)

globalmatch(str2); // (3)
splitjoin(str2);   // (4)

function globalmatch(str) {
  var replaced = str.replace(/"/g, '\\"');
  var start = new Date;
  for (var i = 0; i < 100000; i++) str.replace(/"/g, '\\"');
  alert('globalmatch: ' + str + ' to ' + replaced + ': ' + (new Date - start));
}

function splitjoin(str) {
  var replaced = str.split('"').join('\\"');
  var start = new Date;
  for (var i = 0; i < 100000; i++) str.split('"').join('\\"');
  alert('splitjoin: ' + str + ' to ' + replaced + ': ' + (new Date - start));
}

以下のURLにアクセスすると実行されます.
http://dev.abicky.net/blog/javascript_replaceall.html

結果(ms)

Browser (1) (2) (3) (4)
IE 8 551 911 741 1692
IE 7 991 1692 1242 2855
IE 6 561 1322 762 2364
Firefox 3.6 160 248 369 487
Firefox 3.5 182 448 555 994
Chrome 4 123 373 397 1032
Safari 4 185 246 356 484
Opera 10 3174 781 8642 1882

そんなわけで,Operaを除いては正規表現のグローバルマッチを使った方がそこそこ速いみたいです.
検証で使った7ブラウザ合計のシェアとOperaのシェアを考えると正規表現のグローバルマッチで全置換すべきですかね.

広告
LaTeX数式を表示させるためのPukiWikiプラグイン RでMATLABのrepmat実装
※このエントリーははてなダイアリーから移行したものです。過去のコメントなどはそちらを参照してください