I was considering ways to create arrays containing a default value using native methods and ended up with
function pushMap(length, fill){
var a = [], b = [];
a.length = length;
b.push.apply(b,a);
return b.map(function(){return fill;});
}
Expecting it to be 2 or 3 times slower than a while loop, as the native methods have to loop twice whereas while loops only once, so I compared it on jsperf against
function whileLengthNew(len, val) {
var rv = new Array(len);
while (--len >= 0) {
rv[len] = val;
}
return rv;
}
and it is actually 18 to 27 times slower (tested with Google Chrome on Ubuntu, browsers/OSs welcome).
What is happening that causes such a big difference?
fill(0); The Array. fill() method would take ~210-250ms to fill an array of size 10000000, while the for loop would take ~70-90ms.
In case of multiple iterations of the loop, and where the size of array is too large, for loop is the preference as the fastest method of elements' iteration. While loops perform efficient scaling in case of large arrays.
Because filling array from front means the existing objects need to be pushed to the back first before adding the item at index 0? Thanks. That could be the possible reason. Inserting from front would require shifting rest of elements.
For loop (forward and reverse) The traditional for loop is the fastest, so you should always use that right? Not so fast - performance is not the only thing that matters. Code Readability is usually more important, so default to the style that fits your application.
I would expect that this is due to two major factors:
Memory allocation -- whileLengthNew
creates an array of the correct size first, and then operates on it, pushMap
creates the final array one element at a time with map
. This may cause multiple allocations, especially if the source array is large. (The way that you create the initial a
and b
arrays is basically irrelevant, since map
is building up a new array to return anyway -- it doesn't actually change anything in b
)
Function call overhead -- in your call to map
, you are calling a function for every element of the array. This involves quite a lot of overhead; setting up activation records and scope chains, stack manipulation, and passing the return value back. -- all of this to access a variable which is constant within the function. On top of that, you have set up a closure, so even accessing the fill
variable is slower than it is in the whileLengthNew
version.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With