2016-09-30 24 views
9

私は、JavaScriptの大きなベクトルリストを効率的に処理する方法を探していました。私は、異なるデータ構造を使用してインプレーススカラーとベクトルの乗算を行うsuite of performance testsを作成しました:なぜjavascriptは配列の構造よりも速く構造の配列を処理するのですか?

いるAoS実装:

var vectors = []; 
// 
var vector; 
for (var i = 0, li=vectors.length; i < li; ++i) { 
    vector = vectors[i]; 
    vector.x = 2 * vector.x; 
    vector.y = 2 * vector.y; 
    vector.z = 2 * vector.z; 
} 

SOAの実装:

いるAoS実装は、少なくとも5倍ですもっと早く。これは私を驚かせた。 AoSの実装では、SoA実装よりも反復ごとに1つ多くの索引ルックアップが使用され、エンジンは保証されたデータ型なしで動作する必要があります。

これはなぜ発生するのですか?これはブラウザの最適化によるものですか?キャッシュミス?サイドノートでは

addition over a list of vectorsを行うときに、SOAはまだ少し、より効率的である:

いるAoS:

var AoS1 = []; 
var AoS2 = []; 
var AoS3 = []; 
//code for populating arrays 
for (var i = 0; i < N; ++i) { 
    AoS3[i].x = AoS1[i].x + AoS2[i].x; 
} 

のSoA:

var x1 = new Float32Array(N); 
var x2 = new Float32Array(N); 
var x3 = new Float32Array(N); 
for (var i = 0; i < N; ++i) { 
    x3[i] = x1[i] + x2[i]; 
} 

とき、私が言うことができる方法はあります与えられたデータ構造の操作は、より効率的になるでしょうか?

EDIT 型付き配列を使用してSoAを実装することに重点を置いていませんでした。そのため、このパフォーマンスの動作が私を奇妙に思うのです。型付き配列によって提供されるデータ型の保証があるにもかかわらず、連想配列の普通の配列は高速です。私はこの質問の重複をまだ見ていない。

EDIT2:vectorの宣言を準備コードに移動したときに、この動作が発生しなくなりました。 vectorforループのすぐ隣に宣言されると、AoSは表面上高速になります。これは私にはほとんど意味がありません。特に、エンジンがそれをスコープの上部に固定する必要があるからです。テストフレームワークの問題が疑わしいので、私はこれ以上疑問を呈しません。

EDIT3:I got a responseテストプラットフォームの開発者から、彼らはパフォーマンスの違いが外側のスコープの検索によるものであることを確認しました。 SoAは、依然として予想通り、最も効率的です。

+0

ベンチマークサイトへのリンクとしてではなく、ここにコードを掲載してください。 – Barmar

+0

最新のJavascriptエンジンでは、オブジェクトへのアクセスを特別に最適化しています。 – Barmar

+0

「構造」とは、オブジェクトを意味します。 – OrangeDog

答えて

3

ベンチマークに使用されているテストの構造が互いに重なっているように見え、未定義または望ましくない動作が発生します。クリーナーテスト(https://www.measurethat.net/Benchmarks/Show/474/0/soa-vs-aos)では、両者の違いはほとんどなく、わずかに(30%)実行されるSOAがあります。

ただし、パフォーマンス面での重要な点はありません。これはミクロ最適化の取り組みです。あなたが本質的に比較しているのは、ニュアンスを伴うO(n)からO(n)です。 O(n)が許容可能な時間の複雑さであると考えられるので、小さなパーセント差は全体的に影響を及ぼさない。

+0

"、構造体の配列は繰り返しごとに1回のルックアップしか必要としません。連想配列(「vector.x」など)の属性ルックアップは引き続き検索されます。私はSoAのための6つのルックアップとAoSのための7つのルックアップを数えています。私はあなたがSoAのための追加の3つのルックアップをどこで得るかわかりません。複雑さは同じですが、改善の要因が異なる世界を作り出すアプリケーションがあると考えてください。 – 16807

+0

ルックアップカウントを6に修正しました。これは正確です。 –

+0

アトリビュートのルックアップは、インデックスのルックアップと同じではありません。これは、セットのサイズがルックアップの所要時間に影響するためです。あなたのオブジェクトには少量の属性しかありませんが、セット内の何千ものアイテムが潜在的に存在します。 –