2012-05-06 13 views
3

なぜ新しい配列が遅いのですか?

var fat_cats = new Array(cats.length) 

に操作

var fat_cats = cats.slice() 

を比較したパフォーマンスの違いは混乱しています。

Firefoxで

とクロムnew Arrayは(これは単に混乱です)

IE8 new Arrayのように

高速である(それは速くなる必要がある場合、それだけで空の配列を割り当て、その上に反復処理を行っていない)遅いです

何かありがとうございます。

benchmark

+2

あなたは 'j.slice()'を意味しますか? –

+0

@ NiklasB。ありがとう> _ < – Raynos

+0

@ MahmoudAl-Qudsiどちらかの方法で、それらの値を持つ配列を上書きする – Raynos

答えて

8

V8の配列関数のためthe source codeを見て、それを考え出しました。

配列の要素数が1000を超えており、.sliceが呼び出された場合は、SmartSliceという関数が使用され、それ以外の場合はSimpleSlice関数が使用されます。

SimpleSliceはforループコピーとして実装されます(アレイコピーテストケースのコードとまったく同じです)。一方、SmartSliceは、疎配列を使用してデータを表します。

a test caseでは、要素の数が10,000から1000未満に落とされていますが、まったく同じパフォーマンス(誤差の範囲内)ですが、a better-controlled test caseでは変動が少なく、要素が1000を超えるSmartSliceメソッドは〜ナイーブコピーよりも36%高速です。


これは完全に物事のV8側を説明しながら、Firefoxがスライスされた配列よりも新しいアレイにも遅いですなぜ、私も小さいサイズで、知らない - 彼らは場所で同様の最適化を持っていない限り(おそらくすべてのためにスライス機能)。

EDIT

これは、私を盗聴まま、私はFirefoxのソースをダウンロードしてjs/src/jsarray.cpp!array_sliceをチェックアウトして、Firefoxが同様の最適化を持っている:.sliceの結果はDenseCopiedArrayまたはDenseAllocatedArrayで、V8と明らかに似ています希薄な配列。

+0

'.slice()'は配列をコピーするために使用されるため、新しい配列が作成されます。 – pimvdb

+1

いいえ、それは私の主張です。私は、最初の書き込みまで新しい配列を作成しないと思うので、それまでは同じオブジェクトのエイリアスにすぎませんか? –

+0

グローバル変数でうまくいっている:)これは大きな違いがあることは驚くべきことです。 –

関連する問題