gpt4 book ai didi

JavaScript TypedArray 性能

转载 作者:行者123 更新时间:2023-12-03 03:29:49 26 4
gpt4 key购买 nike

为什么 TypedArray 不如常规数组快?我想存储一些预先计算的整数值,并且需要尽可能快地访问数组。

http://jsperf.com/array-access-speed-2/2

准备代码:

 Benchmark.prototype.setup = function() {
var buffer = new ArrayBuffer(0x10000);
var Uint32 = new Uint32Array(buffer);
var arr = [];
for(var i = 0; i < 0x10000; ++i) {
Uint32[i] = (Math.random() * 0x100000000) | 0;
arr[i] = Uint32[i];
}
var sum = 0;
};

测试1:

sum = arr[(Math.random() * 0x10000) | 0];

测试2:

sum = Uint32[(Math.random() * 0x10000) | 0];

enter image description here

PS:可能是我的性能测试无效,请随时纠正我。

最佳答案

现代引擎会在幕后使用真正的数组,即使你使用Array(如果他们认为可以的话),如果你做了一些让他们认为他们不能做的事情,就会依靠属性映射“数组”使用真正的数组。

另请注意,如 radsoc points outvar buffer = new ArrayBuffer(0x10000) 然后 var Uint32 = new Uint32Array(buffer) 生成一个大小为 0x4000 (0x10000/4) 而不是 0x10000 的 Uint32 数组,因为您给出的 ArrayBuffer 值以字节为单位,但当然每个 Uint32Array 条目有四个字节。以下所有内容都使用 new Uint32Array(0x10000) 来代替 (并且始终如此,甚至在此编辑之前) 来比较苹果与苹果。

所以让我们从 new Uint32Array(0x10000) 开始: http://jsperf.com/array-access-speed-2/11 (遗憾的是,JSPerf 丢失了此测试及其结果,现在完全离线)

graph showing roughly equivalent performance

这表明,由于您以简单、可预测的方式填充数组,因此现代引擎会继续在幕后使用真正的数组(及其性能优势),而不是转移。我们看到两者的性能基本相同。速度上的差异可能与类型转换有关,类型转换采用 Uint32 值并将其作为数字分配给 sum(尽管我很惊讶如果这样的话)类型转换不会延迟...)。

但是添加一些困惑:

var Uint32 = new Uint32Array(0x10000);
var arr = [];
for (var i = 0x10000 - 1; i >= 0; --i) {
Uint32[Math.random() * 0x10000 | 0] = (Math.random() * 0x100000000) | 0;
arr[Math.random() * 0x10000 | 0] = (Math.random() * 0x100000000) | 0;
}
var sum = 0;

...这样引擎就必须依靠老式的属性映射“数组”,并且您会看到类型化数组的性能明显优于老式的数组: http://jsperf.com/array-access-speed-2/3 (遗憾的是,JSPerf 丢失了此测试及其结果)

bar graph showing marked performance improvement for typed arrays

聪明,这些 JavaScript 引擎工程师......

不过,您对 Array 数组的非数组性质所做的具体操作很重要;考虑:

var Uint32 = new Uint32Array(0x10000);
var arr = [];
arr.foo = "bar"; // <== Non-element property
for (var i = 0; i < 0x10000; ++i) {
Uint32[i] = (Math.random() * 0x100000000) | 0;
arr[i] = (Math.random() * 0x100000000) | 0;
}
var sum = 0;

这仍然按预期填充数组,但我们向其中添加了一个非元素属性 (foo)。 http://jsperf.com/array-access-speed-2/4 (遗憾的是,JSPerf 丢失了这个测试及其结果) 显然,引擎非常聪明,将非元素属性放在一边,同时继续使用真正的数组作为元素属性:

bar graph showing performance improvement for standard arrays when <code>Array</code> array gets non-element property

与我们上面的第一个测试相比,我有点无法解释为什么标准数组应该更快。测量误差? Math.random 中的变幻莫测?但我们仍然非常确定 Array 中的数组特定数据仍然是一个真正的数组。

如果我们做同样的事情但以相反的顺序填写:

var Uint32 = new Uint32Array(0x10000);
var arr = [];
arr.foo = "bar"; // <== Non-element property
for (var i = 0x10000 - 1; i >= 0; --i) { // <== Reverse order
Uint32[i] = (Math.random() * 0x100000000) | 0;
arr[i] = (Math.random() * 0x100000000) | 0;
}
var sum = 0;

...我们回到类型化数组获胜的话题——IE11 除外: http://jsperf.com/array-access-speed-2/9 (遗憾的是,JSPerf 丢失了此测试及其结果)

graph showing typed arrays winning except on IE11

关于JavaScript TypedArray 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24853686/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com