when comparing the operation
var fat_cats = cats.slice()
to
var fat_cats = new Array(cats.length)
the performance differences are confusing.
In firefox and chrome new Array
is slower (when it should be faster, it's just allocating an empty array and not doing iteration over it)
Where as in IE8 new Array
is faster (which is just confusing)
Any explanation appreciated.
benchmark
Figured it out by looking at the source code for V8's array functions.
If an array has more than 1000 elements and .slice
is called, a function called SmartSlice
is used, verses the SimpleSlice
function used otherwise.
SimpleSlice
is implemented as a for loop copy (exactly the same as the code in the array copy test case). SmartSlice
, on the other hand, uses sparse arrays to represent the data.
In a test case where the number of elements is dropped from 10,000 to below 1000, they are exactly the same performance (within the margin of error), whereas in a better-controlled test case with fewer variation and more than 1000 elements, the SmartSlice method is ~36% faster than the naïve copy.
While this explains the V8 side of things perfectly, I do not know why Firefox is also slower on new arrays than sliced arrays, even at smaller sizes - unless they have a similar optimization in place (perhaps for all slice functions).
EDIT
This kept bugging me, so I downloaded the Firefox source and checked out js/src/jsarray.cpp!array_slice
, and Firefox does have a similar optimization: the result of .slice
is a DenseCopiedArray
or DenseAllocatedArray
, which is apparently similar to the V8 sparse array.