JavaScriptでマッチ文字列を全置換するにはどうするのが速い?
JavaScriptのStringオブジェクトの文字列置換メソッドであるreplaceは最初にマッチした文字列しか置換しません.replaceAllのようなメソッドも用意されていません.
※str.replace(pattern, replacement, ‘g’)のようにgオプションを指定することによって全置換できるのはFirefoxのみのようです
JavaScriptで全置換する方法として、よく次の2つの方法が挙げられます.
- 検索文字列を正規表現にしてグローバルマッチによる置換
var value = 'Hello World'; value.replace(/o/g, '*');
- 検索文字列で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のシェアを考えると正規表現のグローバルマッチで全置換すべきですかね.