1. ホーム
  2. javascript

[解決済み] JavaScriptのObjects/Arrayの性能は?(特にGoogle V8について)

2022-10-12 21:21:41

質問

JavaScript (特に Google V8) における配列とオブジェクトに関連するパフォーマンスは、文書化するのが非常に興味深いでしょう。 インターネット上のどこにも、このトピックに関する包括的な記事を見つけることができません。

いくつかのオブジェクトは、その基礎となるデータ構造としてクラスを使用することを理解しています。多くのプロパティがある場合、それは時々ハッシュ テーブルとして扱われるのですか?

また、配列はC++の配列のように扱われることがあると理解しています(つまり、高速なランダムインデックス、遅い削除とリサイズ)。 そして、他の時には、それらはよりオブジェクトのように扱われます (高速インデックス、高速挿入/削除、より多くのメモリ)。 また、リンクされたリストとして保存されることもあります(すなわち、遅いランダムインデックス、最初と最後の高速削除/挿入)。

JavaScript における配列/オブジェクトの取得と操作の正確なパフォーマンスはどのようなものですか? (特にGoogle V8について)

より具体的には、それはどのようなパフォーマンスの影響です。

  • オブジェクトにプロパティを追加する
  • オブジェクトからプロパティを削除する
  • Object のプロパティをインデックス化する
  • Arrayにアイテムを追加する
  • 配列から項目を削除する
  • 配列内の項目のインデックスを作成する
  • Array.pop()を呼び出す
  • Array.push()の呼び出し
  • Array.shift()の呼び出し
  • Array.unshift()の呼び出し
  • Array.slice()の呼び出し

もっと詳しい記事やリンクがあれば、それもお願いします :)

EDITです。 JavaScriptの配列やオブジェクトがどのような仕組みで動いているのか、とても気になります。 また、どのような コンテキスト V8 エンジンは、別のデータ構造に切り替えることを承知しているのでしょうか?

例えば、私が...で配列を作成したとします。

var arr = [];
arr[10000000] = 20;
arr.push(21);

本当はどうなんだろう?

それとも...これはどうなんだろう...?

var arr = [];
//Add lots of items
for(var i = 0; i < 1000000; i++)
    arr[i] = Math.random();
//Now I use it like a queue...
for(var i = 0; i < arr.length; i++)
{
    var item = arr[i].shift();
    //Do something with item...
}

従来の配列の場合、パフォーマンスはひどいものでしたが、LinkedListを使用した場合は...それほど悪くありません。

どのように解決するのか?

私が作成した テストスイートを作成しました。 ( アーカイブされたコピー ).

そしてその意味で、この50以上のテストケースのテスターでパフォーマンスの問題を見ることができます(長い時間がかかりますが)。

また、その名前が示すように、DOM 構造のネイティブなリンクされたリストの性質を使用する方法を調査しています。

(現在停止中、再構築中) この件に関する詳細は、私のブログで紹介しています。 .

概要は以下の通りです。

  • V8 アレイは高速、非常に高速です。
  • 配列のプッシュ/ポップ/シフトは、同等のオブジェクトよりも約 20 倍以上高速です。
  • 意外なことに Array.shift() は配列のポップよりも約6倍遅いが、オブジェクトの属性削除よりも約100倍速い。
  • 面白いことに Array.push( data ); よりも速いのです。 Array[nextIndex] = data のほぼ 20 倍 (動的配列) から 10 倍 (固定配列) の速度で動作します。
  • Array.unshift(data) は予想通り遅く、新しいプロパティを追加するよりも約 5 倍も遅くなります。
  • 値を Null にする array[index] = null は削除するよりも速いです。 delete array[index] (未定義) を配列で削除するよりも ~約 4x++ 速くなります。
  • 驚くべきことに、オブジェクト内の値を Null にすることは obj[attr] = null ~属性を削除するよりも約 2 倍遅くなります。 delete obj[attr]
  • 当然のことながら、中間配列の Array.splice(index,0,data) は遅いです、非常に遅いです。
  • 意外と Array.splice(index,1,data) は最適化され (長さは変更されません)、単なるスプライスよりも100倍高速です。 Array.splice(index,0,data)
  • を除くすべてのセクタで、divLinkedList は配列より劣っています。 dll.splice(index,1) の削除 (テスト システムを破壊した場所) を除いて、すべてのセクターで配列に劣ります。
  • 最大の驚き V8の配列の書き込みは、V8の読み込みよりわずかに速いということだ =O

注意してください。 これらのメトリクスは、v8が完全に最適化しない大きな配列/オブジェクトにのみ適用されます。配列/オブジェクトのサイズが任意のサイズ (24?) 未満の場合、非常に孤立した最適化されたパフォーマンス ケースがあります。詳細はgoogleのIOビデオで見ることができます。

注2: これらの素晴らしいパフォーマンス結果は、ブラウザ間で共有されておらず、特に *cough* IEです。また、テストは膨大で、それゆえ私はまだ結果を完全に分析および評価できていません。)

更新情報 (2012年12月)。 Googleの担当者は、クローム自体の内部動作(リンクリスト配列から固定配列に切り替わるときなど)や、最適化の方法を説明したビデオをYouTubeにアップしています。参照 GDC 2012 コンソールからクロームへ をご覧ください。