为什么数组文字和 BufferArray 之间的性能差距如此之大?

Why is the performance gap between array literals and BufferArray so big?

我试图了解 js 中的 ArrayBuffer,因为它是线程和工作线程之间可传输的类型之一。

我发现变量创建存在巨大的性能差距,而且我无法在 Internet 上找到答案。

我尝试了几个基准测试,数组文字总是比 TypedArrays 声明快得多。我在节点 11、chrome 和 firefox 中试过,结果一致。

var LIMIT = 10000;
console.time("Array insertion time");
for (var i = 0; i < LIMIT; i++) {
    var arr = new Array();
}
console.timeEnd("Array insertion time");


console.time("ArrayBuffer insertion time");
for (var i = 0; i < LIMIT; i++) {
  var buffer = new ArrayBuffer(LIMIT * 4);
  var arr = new Int32Array(buffer);
}
console.timeEnd("ArrayBuffer insertion time");

我收到了疯狂的结果:
数组插入时间:1.283ms
ArrayBuffer插入时间:53.979ms

我认为 JS 引擎声明一个 TypedArray 会比声明一个 litteral 更快。我认为 ArrayBuffer 是一个非常优化的调用,用于为程序分配内存。

原始类型通常总是会更快。它们的使用如此频繁,以至于它们在引擎优化方面得到了最多的关注。类型化数组很可能有更多开销,因为它们对插入等操作执行类型检查。这不是免费的。

此外,您的第二个示例在声明缓冲区然后将其转换为类型化数组方面做了更多工作。您还执行非常小的操作,其中 ArrayBuffers 旨在存储更大的长缓冲区,如二进制音频或图像。

你根本就不是在做同样的事情...

当你声明一个ArrayBuffer时,浏览器会要求一个静态内存槽,这个ArrayBuffer的大小。
另一方面,数组没有静态内存槽,它会在更新长度时被重新分配。

所以如果你想执行一个公平的测试,那么你需要在这些数组中分配一些数据,因为目前,它们对于引擎而言只是空对象,即它们具有非常低的 foot-print,生成速度非常快。

var LIMIT = 5000; // I have to lower the LIMIT because Array is so slow
console.time("Array insertion time");
for (var i = 0; i < LIMIT; i++) {
  // to be fair, they should hold the same data
  var arr = new Array(LIMIT * 4).fill(0);
}
console.timeEnd("Array insertion time");


console.time("ArrayBuffer insertion time");
for (var i = 0; i < LIMIT; i++) {
  var buffer = new ArrayBuffer(LIMIT * 4);
  var arr = new Int32Array(buffer);
}
console.timeEnd("ArrayBuffer insertion time");