私は、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
の宣言を準備コードに移動したときに、この動作が発生しなくなりました。 vector
がfor
ループのすぐ隣に宣言されると、AoSは表面上高速になります。これは私にはほとんど意味がありません。特に、エンジンがそれをスコープの上部に固定する必要があるからです。テストフレームワークの問題が疑わしいので、私はこれ以上疑問を呈しません。
EDIT3:I got a responseテストプラットフォームの開発者から、彼らはパフォーマンスの違いが外側のスコープの検索によるものであることを確認しました。 SoAは、依然として予想通り、最も効率的です。
ベンチマークサイトへのリンクとしてではなく、ここにコードを掲載してください。 – Barmar
最新のJavascriptエンジンでは、オブジェクトへのアクセスを特別に最適化しています。 – Barmar
「構造」とは、オブジェクトを意味します。 – OrangeDog