168*_*807 9 javascript performance
我一直在寻找一种有效的方法来处理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;
}
Run Code Online (Sandbox Code Playgroud)
SoA实施:
var x = new Float32Array(N);
var y = new Float32Array(N);
var z = new Float32Array(N);
for (var i = 0, li=x.length; i < li; ++i) {
x[i] = 2 * x[i];
y[i] = 2 * y[i];
z[i] = 2 * z[i];
}
Run Code Online (Sandbox Code Playgroud)
AoS实施至少快5倍.这令我感到意外.与SoA实现相比,AoS实现每次迭代使用一次索引查找,并且引擎必须在没有保证数据类型的情况下工作.
为什么会这样?这是由于浏览器优化吗?缓存未命中?
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;
}
Run Code Online (Sandbox Code Playgroud)
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];
}
Run Code Online (Sandbox Code Playgroud)
有什么方法可以判断某个操作对于给定的数据结构是否会更高/更低效?
编辑:我没有强调使用类型数组的SoA实现,这就是为什么这种性能行为让我觉得奇怪.尽管有类型数组提供的数据类型保证,但是关联数组的普通数组更快.我还没有看到这个问题的重复.
EDIT2:我发现当声明vector移动到准备代码时不再发生这种行为.当vector声明在for循环旁边时,AoS表面上更快.这对我来说没什么意义,特别是因为引擎应该只是将它固定在示波器的顶部,无论如何.我不打算进一步质疑,因为我怀疑测试框架存在问题.
编辑3:我得到了测试平台开发人员的回复,他们已经确认性能差异是由于外部范围查找造成的.正如预期的那样,SoA仍然是效率最高的.
用于基准测试的测试结构似乎相互重叠,导致未定义或不期望的行为。更清晰的测试 ( https://www.measurethat.net/Benchmarks/Show/474/0/soa-vs-aos ) 显示两者之间几乎没有什么区别,并且 SOA 执行速度稍快 (30%)。
然而,就性能而言,这些都对底线无关。这是微观优化的努力。您本质上比较的是 O(n) 到 O(n),其中涉及细微差别。小百分比差异不会产生总体影响,因为 O(n) 被认为是可接受的时间复杂度。