javascript - 为什么 javascript 处理结构数组比处理数组结构更快?

标签 javascript performance

我一直在寻找一种有效的方法来处理 javascript 中的大型向量列表。我创建了一个 suite of performance tests使用不同的数据结构执行就地标量向量乘法:

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 实现:

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];
}

AoS 实现至少快 5 倍。这让我很吃惊。 AoS 实现比 SoA 实现在每次迭代中多使用一次索引查找,并且引擎必须在没有保证数据类型的情况下工作。

为什么会出现这种情况?这是由于浏览器优化吗?缓存未命中?

附带说明一下,SoA 在执行 addition over a list of vectors 时仍然稍微高效一些。 :

服务质量:

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];
}

有没有一种方法可以判断某个操作对于给定数据结构的效率何时会提高/降低?

编辑:我没有强调 SoA 实现使用了typed arrays,这就是为什么这种性能行为让我感到奇怪的原因。尽管有类型化数组提供的数据类型保证,但关联数组的普通旧数组更快。我还没有看到这个问题的副本。

EDIT2:我发现当 vector 的声明被移动到准备代码时,该行为不再发生。当在 for 循环旁边声明 vector 时,AoS 表面上更快。这对我来说意义不大,特别是因为无论如何引擎都应该将它锚定在范围的顶部。我不打算进一步质疑这个问题,因为我怀疑测试框架有问题。

编辑 3:我 got a response来自测试平台的开发人员,他们已经确认性能差异是由于外部范围查找造成的。正如预期的那样,SoA 仍然是最高效的。

最佳答案

用于基准测试的测试结构似乎相互重叠,导致未定义或不需要的行为。更清晰的测试 ( https://www.measurethat.net/Benchmarks/Show/474/0/soa-vs-aos ) 显示两者之间几乎没有区别,并且 SOA 的执行速度稍快 (30%)。

但是,就性能而言,这些都无关紧要。这是微观优化的努力。您本质上要比较的是 O(n) 到 O(n),其中包含细微差别。小的百分比差异不会对整体产生影响,因为 O(n) 被认为是可接受的时间复杂度。

关于javascript - 为什么 javascript 处理结构数组比处理数组结构更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39799874/

相关文章:

ios - 在我的 iOS 应用程序中遇到严重的性能问题

javascript - 如何使用 html 或 jsp 将数据以 xml 形式发布到服务器

javascript - 多个 Angular 5 组件操纵一个中心组件

javascript - 关于新网站 DIV 刷新的警报

javascript - 您如何从 JavaScript API 获取 OAuth token ?

sql - 使用 JOIN 而不是 HAVING(COUNT > n) 来提高性能

sql - MySQL MyISAM 表性能问题重温

java - 如何让正则表达式更加高效?

javascript - 单击时从 jquery 可排序列表中删除一个元素

字典查找(字符串键)与列表索引之间的 Python 性能差异