Suk*_*lay 20 javascript performance typed-arrays
为什么TypedArrays不像通常的数组那么快?我想为CLZ使用precalc值(计算前导零函数).而且我不希望他们像往常一样解释对象?
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;
};
Run Code Online (Sandbox Code Playgroud)
测试1:
sum = arr[(Math.random() * 0x10000) | 0];
Run Code Online (Sandbox Code Playgroud)
测试2:
sum = Uint32[(Math.random() * 0x10000) | 0];
Run Code Online (Sandbox Code Playgroud)

PS可能是我的性能测试无效随时纠正我.
T.J*_*der 35
现代引擎将在幕后使用真正的数组,即使你Array认为他们可以使用它们,如果你做了让他们认为不能使用真正数组的东西,那么就回到属性映射"数组".
还要注意,当radsoc指出时,var buffer = new ArrayBuffer(0x10000)然后var Uint32 = new Uint32Array(buffer)产生一个Uint32数组,其大小为0x4000(0x10000/4),而不是0x10000,因为你给出的值ArrayBuffer是以字节为单位,但当然每个Uint32Array条目有4个字节.所有的下方使用new Uint32Array(0x10000),而不是(和往常一样,即使此编辑之前)与苹果比较苹果.
所以让我们从那里开始new Uint32Array(0x10000):http ://jsperf.com/array-access-speed-2/11(遗憾的是,JSPerf已经失去了这个测试及其结果,现在完全脱机)

这表明,由于您以简单,可预测的方式填充阵列,现代引擎继续使用真正的阵列(具有其性能优势)而不是转移.我们看到两者的表现基本相同.速度的差异可能与获取Uint32值并将其分配sum为a的类型转换有关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;
Run Code Online (Sandbox Code Playgroud)
...所以引擎必须依赖于老式的属性映射"数组",你会发现类型化的数组明显优于传统类型:http ://jsperf.com/array-access-speed-2/3(遗憾的是,JSPerf已经失去了这个测试及其结果)

聪明,这些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;
Run Code Online (Sandbox Code Playgroud)
这仍然可以预测地填充数组,但是我们foo为它添加了一个非元素属性().http://jsperf.com/array-access-speed-2/4 (遗憾的是,JSPerf已经失去了这个测试及其结果)显然,引擎非常聪明,并且将这些非元素属性保留在一边,同时继续对元素属性使用true数组:
Run Code Online (Sandbox Code Playgroud)
...我们回到打出的类型阵列 - 除了IE11:http ://jsperf.com/array-access-speed-2/9(遗憾的是,JSPerf已经失去了这个测试及其结果)

rad*_*soc 34
var buffer = new ArrayBuffer(0x10000);
var Uint32 = new Uint32Array(buffer);
Run Code Online (Sandbox Code Playgroud)
与以下内容不同:
var Uint32 = new Uint32Array(0x10000);
Run Code Online (Sandbox Code Playgroud)
不是因为新的ArrayBuffer(你总是得到一个数组缓冲区:在两种情况下都看到Uint32.buffer)但由于长度参数:对于ArrayBuffer,每个元素有1个字节,Uint32Array每个元素有4个字节.
因此,在第一种情况下(以及在您的代码中),Uint32.length = 0x1000/4并且您的循环超出了4次中的3次.但遗憾的是,你永远不会得到错误,只有糟糕的表现.
使用'new ArrayBuffer',你必须像这样声明Uint32:
var buffer = new ArrayBuffer(0x10000 * 4);
var Uint32 = new Uint32Array(buffer);
Run Code Online (Sandbox Code Playgroud)
请参阅jsperf(0x10000)和jsperf(0x10000*4).
| 归档时间: |
|
| 查看次数: |
11895 次 |
| 最近记录: |