Search code examples
javascriptarraybuffer

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


I try to understand about the ArrayBuffer in js as it one of the transferable types between a thread and a worker.

I find huge performance gap into variable creation and I'm unable to find an answer over the internet.

I tried several benchmarking and arrays litterals are always much much more faster to declare than TypedArrays. I tried in node 11, chrome and firefox, results are coherent.

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");

I receive crazy results:
Array insertion time: 1.283ms
ArrayBuffer insertion time: 53.979ms

I thought it would be faster for JS Engine to declare a TypedArray than a litteral. I thought ArrayBuffer was a very optimized call for allocating memory to the programm.


Solution

  • You are simply not doing the same thing at all...

    When you declare an ArrayBuffer, the browser will ask for a static memory slot, the size of this ArrayBuffer.
    An Array on the other hand doesn't have a static memory slot, it will get reassigned while its length will get updated.

    So if you want to perform a fair test, then you need to assign some data in these Arrays, because currently, they're just empty objects for what the engine is concerned, i.e they have a very low foot-print, and are very fast to generate.

    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");