2011-07-01 14 views
5

誰かが私にこれを説明することができます:JavaScriptの文字列の連結スピード

http://jsperf.com/string-concatenation-1/2

あなたが怠け者なら、私はB対)Aをテストしました):

A)

var innerHTML = ""; 

items.forEach(function(item) { 
    innerHTML += item; 
}); 

B)

var innerHTML = items.join(""); 

ここで、両方のテストのitemsは同じ500要素の文字列配列で、各文字列はランダムで長さは100〜400文字です。

)は、10倍速くなります。どのようにすることができますか?私はいつもjoin("")を使って連結することが最適化のトリックだと思っていました。私のテストに何か欠陥がありますか?

+0

非常に多数の文字列に参加していない限り(非常に大きいブラウザに依存します)、 'Array.Join'は遅くなり、' + ' – Mrchief

答えて

8

join("")を使用すると、O(n**2)のバッファコピーを避けるために、IE6で大きな文字列を構成する最適化のトリックとなりました。 O(n**2)は、大規模なnの配列のオーバーヘッドを実際に支配するだけなので、小さな文字列を構成する上で大きなパフォーマンス上の勝利は期待されませんでした。

現代のインタプリタは、「依存する文字列」を使用してこれを回避します。依存文字列といくつかの利点と欠点の説明については、mozilla bugを参照してください。

は基本的に、現代の通訳は、ストリングの異なる種類の数を知っている:

  1. 別の文字列の文字の配列
  2. スライス(サブストリング)
  3. 他の二つの文字列
  4. の連結

これは、部分文字列バッファをあまりにも多く保存することを時々犠牲にして、連結および部分文字列O(1)を生み出し、その結果、ガーベットが非効率または複雑になる電子コレクタ。

最新のインタプリタの中には、ASCIIのみの文字列の場合には(1)をバイト[]に分解するアイデアや、文字列に1文字に収まらないUTF-16コードユニットが含まれる場合のuint16の配列バイト。しかし、そのアイデアが実際に通訳に含まれているかどうかはわかりません。

1

@Mike Samuelが語っているLuaプログラミング言語explains the buffer overheadの著者です。例はLuaにありますが、問題はJavaScriptでも同じです。