Javascriptのメモリレイアウト-データ指向とオブジェクト指向の設計[閉じました]
-
21-12-2019 - |
質問
C/C++の背景から来て、キャッシュミスを減らすことに関するオブジェクトのメモリレイアウトは、特にコンソールで作業するときに重要なものです。データ指向設計は、関連するオブジェクトをメモリ内(特にパフォーマンスが重要な領域)で互いに近くに保つのを助けるために、オブジェクト指向設計よりも好まれることがよくあります。
最近、私はいくつかのJavascript開発を行ってきましたが、Javascriptコミュニティ内で一般的なコンセンサスが何であるか疑問に思っています。
Javascriptでの私の限られた経験では、プロファイリング時に完全に予想外の結果を見て驚いたことがよくあります。Javascriptオブジェクト/構造の内部メモリのレイアウトと実装はブラウザごとに大きく異なるため、最適化を試みる価値があるのではないかと思います。
簡単なテストケースを作成しました(http://jsperf.com/object-vs-data)jsPerfでは2つの方法のパフォーマンスを比較し、Chromeではパフォーマンスの向上を示していますが、Safariでは顕著な高速化はありません。
Javascriptでは、オブジェクトのメモリレイアウトにも気を配る必要がありますか?それとも、「1つの方法で実装し、必要に応じて最適化する」タイプのものですか?
この2番目のオプションは、特に従うべき良いガイドラインがある場合、(開発時間の点で)一種の無駄に思えます。
ありがとう~
補足情報:これは基本的に私がJavascriptで2つのアプローチを実装する方法です。上記のjsPerfテストケースは次のように実装されています。
var objectOriented = [
{ foo: 1, bar: 2 },
{ foo: 3, bar: 4 }
];
var dataOriented = {
foos: [1, 3],
bars: [2, 4]
};
// Object-oriented access:
var a = objectOriented[0].bar;
// Data-oriented access:
var b = dataOriented.bars[0];
解決
JavascriptのオブジェクトはC++のように動作するという基本的な前提から作業しています。彼らはしません。
C++では、型の主な目的は、メモリのチャンク上で「レンズ」として機能することです。クラスレイアウトは、オブジェクトが記述するメモリの内容を、明確に定義された方法で直接定義します。C/C++配列には、特に同種の型の線形で連続的なレイアウトが必要です。
JavaScriptでは、オブジェクトは名前と値のペアのコレクションです。配列は、特別な「長さ」プロパティを持つ単なるオブジェクトです。ここにはメモリレイアウトの説明や定義がないことに注意してください。Javascriptインタプリタが線形のメモリチャンクではなくハッシュテーブルとして配列を実装するのを止めるものは何もありません;実際、私はそれらがまさにそれを行うJS実装であると確信しています。
JavaScriptの実装は自由にメモリをレイアウトできますが、ソースで行うことと実際にマシンで終わることとの間には対応関係はありません。
さらに、JavaScript配列は異種であり、均質ではありません。つまり、連続したメモリにレイアウトされていると仮定すると、Cの同等の型はint**(またはfloat**など)ではなくJSObject**になります。JS配列は、他の場所に保存されているデータへの参照のコレクションであるため、参照がキャッシュラインにあっても、データはそうではありません。
だから、要約すると-この種の思考はあなたに痛みだけを得るでしょう。JavaScriptはC++よりもはるかに高いレベルの言語であり、その一部はあなたが慣れている制御を放棄しています。可能であれば、そのような低レベルの最適化はインタプリタによって行われます。解決策を自然に表現する効率的なアルゴリズムでコードを書くことに集中してください;それはそのままでは十分に難しいです。:-)
他のヒント
わかったいくつかの数字とテストケースをいじった。.
まず、このテストケースを作成しました http://jsperf.com/object-vs-array-creation-for-so
この場合、以下のように作成します。 Object
は 方法より速く を作成して、 Array
次に、このテストケースを作成しました http://jsperf.com/accessing-speed この点で、それらの間にはほとんど違いはありませんでした。.
したがって、このプロファイルから推測するのは、プロジェクトが次の場合、配列よりもオブジェクトを使用する方が高速であるということです 本当に巨大な..最初のケースから、オブジェクトの作成は配列の作成よりも高速であることは明らかです。
しかし。.
Javascriptは高度に開発されたパフォーマンスの高い言語であり、そのようなマイクロ最適化を心配する必要はありません。あなたが焦点を当てるべきであるすべてはにあります セマンティクス.あなたの意図を最もよく説明する構造を選択する必要があります。.
Windows NT6.3上のChrome36.0.1985.125でのテスト