V 8エンジンはJS配列に対していくつかの最適化を実現します.

13689 ワード

まず2つの例をあげましょう.
var t = new Array(200000); console.time('time1'); for (var i = 0; i < 200000; ++i) {t.push(1);} console.timeEnd('time1');
var t = []; console.time('time2'); for (var i = 0; i < 200000; ++i) {t.push(1);} console.timeEnd('time2');
各ブラウザコントロールの下で出力状況を見ることができます.
chrome
time 1:59109.000 ms
time 2:379.000 ms
FireFox
time 1:509 ms
time 2:461 ms
IE
time 1:351 ms
time 2:356 ms
StockOverflowで見た結論は以下の通りです.
配列インデックスが0からlength-1までの間に、穴がない場合は、このエンジンはC言語の配列で実現されますので、非常に速いです.
配列に穴がある場合、エンジンはハッシュ・テーブルで実装され、これはC配列よりかなり遅い.
例外は、事前に割り当てられた配列の長さが100000以下であれば、エンジンは依然としてC配列で実現されます.この時、配列には穴があり、速度が0-!
以下のコードはこの点を説明しています.
var t = new Array(99999); console.time('time1'); for (var i = 0; i < 200000; ++i) {t.push(1);} console.timeEnd('time1');
var t = new Array(99999+1); console.time('time2'); for (var i = 0; i < 200000; ++i) {t.push(1);} console.timeEnd('time2');
chromeで運転した結果は以下の通りです.
time 1:447.00 ms
time 2:4110.000 msms
これらだけではなく、もっと不思議な例を二つお願いします.
var t = new Array(180000); console.time('time1'); for (var i = 0; i < 200000; ++i) {t.push(1);} console.timeEnd('time1');
var t = new Array(181000); console.time('time2'); for (var i = 0; i < 200000; ++i) {t.push(1);} console.timeEnd('time2');
chrome出力は以下の通りです.
time 1:4165.000 ms
time 1:59034.000 ms
これについては次のように説明します.
V 8エンジンの発見アルゴリズムは、条件に合致する辞書(ハッシュテーブル)モードの配列を高速(C配列)モードに変換する.配列が辞書モードにあるとき、V 8は配列が十分に圧縮されているかどうかを検査し、辞書配列の代わりに連続C配列を使用することが空間的に有利であるかどうかを調べる.
上記の2つの例では、第一の例はC配列に置き換えられ、第二の例は空間的に大きな利点を持たないと、リターンされない.
締め括りをつける
V 8の配列に対する最適化のステップは以下の通りである.
  • プリキャスト配列長は100000以下、または配列に穴がなく、下の層はC配列で実現される.空間交換時間
  • プリキャスト配列長は100000より大きく、配列には穴があり、下の層はハッシュテーブルで実現される.時間変換空間
  • は辞書モード(ハッシュ・テーブル実装)の配列にあり、V 8の発見アルゴリズムは、空間占有量を確認し、その空き要素がある程度減少すると、それを高速モード(C配列)に変換する.