qarthandso
qarthandso

Reputation: 2190

Advanced JavaScript Array Concatenation - Performance

I'm trying out two different ways of joining two arrays and using huge arrays to judge their performances but I'm getting an error on the second option and I don't understand why.

I first filled both with 10,000,000 elements with values equal to their index.

var arr1 = [];
var arr2 = [];
for (var i = 0; i < 10000000; i++) {
    arr1[i] = i;
} 
for (var i = 0; i < 10000000; i++) {
    arr2[i] = i;
}

Then:

Option 1 completes fine in ~520ms:

var newArr = arr1.concat(arr2);

Option 2 though throws the following error:

Array.prototype.push.apply(arr1, arr2);

Error:

/private/var/folders/j6/3fs5_k3n17z_0j2xrwj6sphw0000gn/T/CodeRunner/Untitled 9.js:12
Array.prototype.push.apply(arr1, arr2);
                     ^

RangeError: Maximum call stack size exceeded
    at Object.<anonymous> (/private/var/folders/j6/3fs5_k3n17z_0j2xrwj6sphw0000gn/T/CodeRunner/Untitled 9.js:12:22)
    at Module._compile (module.js:435:26)
    at Object.Module._extensions..js (module.js:442:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)
    at Function.Module.runMain (module.js:467:10)
    at startup (node.js:136:18)
    at node.js:963:3

Edit

Per one of the comments, I changed Option 2 to:

setTimeout(function () {
    Array.prototype.push.apply(arr1, arr2);
}, 0);

And I'm still getting:

/private/var/folders/j6/3fs5_k3n17z_0j2xrwj6sphw0000gn/T/CodeRunner/Untitled 9.js:16
    Array.prototype.push.apply(arr1, arr2);
                         ^

RangeError: Maximum call stack size exceeded
    at null._onTimeout (/private/var/folders/j6/3fs5_k3n17z_0j2xrwj6sphw0000gn/T/CodeRunner/Untitled 9.js:16:23)
    at Timer.listOnTimeout (timers.js:92:15)

Upvotes: 2

Views: 225

Answers (1)

Oleg V. Volkov
Oleg V. Volkov

Reputation: 22421

The apply() method unrolls provided array to arguments list. ECMAScript specification itself have no limits on amount of arguments for function, but most JS engines have implementation-specifc limits because they use fixed or limited size structure for each function call on their internal stack for performance purposes. Though this limit is generally pretty high, it is certainly well below 10000000 arguments and that's why you get error "Maximum call stack size exceeded".

Upvotes: 4

Related Questions