即使您使用Array
,现代引擎也会在幕后使用真实数组,如果您认为他们可以使用Array
,如果您执行的操作使他们认为无法使用真数组,则会回退到属性映射“数组”。
还要注意,如radsoc points out,var buffer = new ArrayBuffer(0x10000)
然后var Uint32 = new Uint32Array(buffer)
产生UINT32数组,其尺寸是0x4000的(0x10000的/ 4),而不是为0x10000,因为你给ArrayBuffer
值以字节为单位,但当然也有每Uint32Array条目四个字节。以下全部使用new Uint32Array(0x10000)
而不是(并且始终如此,甚至在此编辑之前)来比较苹果和苹果。
所以,让我们从这里开始,与new Uint32Array(0x10000)
:http://jsperf.com/array-access-speed-2/11(可悲的是,JSPerf已经失去了本次测试及其结果,而现在处于脱机状态完全)
这表明,因为你”以简单,可预测的方式重新填充阵列,现代引擎继续使用真正的阵列(以及其性能优势),而不是转移。我们看到两者的表现基本相同。速度的差异可能与类型转换有关,其中的值为Uint32
,并将其作为sum
作为number
(尽管如果该类型转换未延迟,我感到很惊讶...)。
添加一些混乱,但:
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已经失去了这个测试及其结果)
聪明,这些JavaSc ript引擎工程师...
但是,您对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已经失去了这个测试及其结果)显然,引擎是相当聪明,并保留非元素属性到一边,而继续使用的元素属性一个真正的数组:
我在一个小的损失来解释为什么标准阵列应该得到更快有相比,我们的第一个测试上方。测量错误?迷宫在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有失去了这个测试及其结果)
您是否删除了jsperf测试?我无法再访问它们 – Bergi
不,我没有删除它。这很奇怪。 –
很奇怪,他们会像那样消失!所有这些......根据[这个FAQ条目](http://jsperf.com/faq#test-availability)特别奇怪。我搜索过万一URL改变了,或者什么都没有。我可以找到阵列表现的其他测试,但不是Sukhanov和我的。我提出了一个[问题](https://github.com/mathiasbynens/jsperf.com/issues/197)。当然,如果我们中的更多人[捐献给jsPerf](http://jsperf.com/faq#donate)(我刚刚做了......第一次*鸭头*),它可能不会受到伤害。 –