Reputation: 5826
When doing some performance tests today I found that Array.from
's callback work pretty slower than running the Array.map
function independently.
Tests were done on 32000000 items long array in the following manner.
let t1;
const arr = Array.from(new Array(32000000), (v,i) => {
if (i === 0) t1 = performance.now();
return i;
});
let t2 = performance.now();
t2 - t1; // ~4500ms
let arr2 = Array.from(new Array(32000000));
arr2 = arr2.map((v,i) => {
if (i === 0) t1 = performance.now();
return i;
});
t2 = performance.now();
t2 - t1; // ~500ms
I always thought the Array.from
just runs the map
function on itself when the array gets created. The polyfills' code looks alike too. Any idea why is there such a difference in performance?
Tested in Google Chrome 74.0.3729.157, macOS
Upvotes: 3
Views: 1462
Reputation: 28157
It's not the mapping function that is slow, it is the Array.from
call itself.
If we remove all the unnecessary variables and conditional statements we get the following simplified benchmark, which returns:
Chrome 74:
Array.from with map: 4735.970ms
Array.map: 166.405ms
Array.map with from: 5101.585ms
Array.from: 4999.910ms
Firefox 67:
Array.from with map: 729.000ms
Array.map: 41.000ms
Array.map with from: 1150.000ms
Array.from: 619.000ms
So we can see that the mapping actually takes almost no time, all that is taking the bulk time is the Array.from
call.
I assume Array.from
is a lot slower to allocate memory for and create the new Array than the one returned by Array.map
just because it is a lot more generic and complex than the map function. Just compare their specs: Array.prototype.map vs Array.from, Array.from
seems a lot harder to optimize the compiler for.
const arr = new Array(32000000);
console.time('Array.from with map');
const arr1 = Array.from(arr, (v,i) => {
return i;
});
console.timeEnd('Array.from with map');
console.time('Array.map');
const arr2 = arr.map((v,i) => {
return i;
});
console.timeEnd('Array.map');
console.time('Array.map with from');
const arr3 = Array.from(arr).map((v,i) => {
return i;
});
console.timeEnd('Array.map with from');
console.time('Array.from');
const arr4 = Array.from(arr);
console.timeEnd('Array.from');
Upvotes: 3