DEV Community

Henry Williams
Henry Williams

Posted on

Array.map() much slower than for loop

I was working on some coding challenges when I got the sudden urge to test which approach was faster. For an input size of 1 million numbers, Array.map() takes about 2,000ms, whereas a for loop takes about 250ms. Any ideas why?

const INPUT_SIZE = 10 ** 7
const input = []
for(let i = 1; i <= INPUT_SIZE; i++) {
    input.push(i)
}

const pow2 = value => value ** 2

console.time('map')
const mapResult = input.map(pow2)
console.timeEnd('map') // 1800-2000+ ms

console.time('loop')
const arrayResult = []
for(let i = 0; i < input.length; i++) {
    arrayResult.push(pow2(input[i]))
}
console.timeEnd('loop') // 200-300ms
Enter fullscreen mode Exit fullscreen mode

I always assumed Array.map() would be faster since it's a built-in function, but it looks like I was wrong.

Test 2

So after thinking about this for a while, I decided to perform a more fair comparison: Array.forEach() vs for loop. The results were that Array.forEach() is still slower, but not by as much as .map() (550-700ms).
My guess is that .map() performs some additional logic that slows it down significantly compared to a raw for loop.

Edit: I'm aware that this isn't exactly a practical scenario as we shouldn't be processing this much data using Javascript. This scenario is for theoretical understanding and discussion.

Top comments (15)

Collapse
 
jessev6 profile image
Jesse Verbruggen

This actually is a lot slower since mapping an array will create a copy of each value in order to not modify the original array.

Since a for loop does not copy the values but rather just accesses them using their index, it is a lot faster.

This peformance difference is only noticable when you have a large amount of data. For smaller amounts of data, it's better to write code which feels more natural to you, which may explain why map is used so commonly.

Collapse
 
henryjw profile image
Henry Williams

Thanks for the perspective. I'm going to try out the same test with creating a copy of each value in the for loop

Collapse
 
avatarkaleb profile image
Kaleb M • Edited

Hi Henry,

Thanks for posting this and doing a test. It's really difficult to truly test out timing of code utilizing timestamps. I recommend the two resources below to better test, because in most cases, the performance of our code is very difficult to measure properly. I'd love to see the results of doing it with a proper test for sure, and how often one has a use case for 1 mill rows of data, since it would be really helpful for us :).

Benchmarking code requires quite a bit of stats and has many factors that are hard to bench mark without a library.

I'd recommend using benchmarkjs.com/ to do your bench marking, and potentially read github.com/getify/You-Dont-Know-JS... to better understanding the proper way to do benchmarking.

I hope that helps!

Collapse
 
henryjw profile image
Henry Williams

Thanks for the recommendations. I'll definitely check out You Don't Know JS.

Collapse
 
atwright147 profile image
Andy Wright

It is slower because it has to create / initialise the callback function passed to it for every item.

There might be other reasons too

Collapse
 
diek profile image
diek

As you say, and i want to add something, the map tool returns you an array with the result of every element through the callback, if you don't want this you shouldn't use it.

Collapse
 
henryjw profile image
Henry Williams

But isn't that essentially what the for loop is also doing?

Thread Thread
 
atwright147 profile image
Andy Wright

Correct. However, you should avoid using the for loop in general, because it will iterate over every property of the item passed to it including things which you might not want to iterate over (like a for in loop would do).

Alternatives to for include: forEach, for of, map etc

Collapse
 
s3pt1c4n profile image
Richard Pap

Exactly

Collapse
 
cirospaciari profile image
Ciro Spaciari

I put your code in a function and i get a perfomance hit in first call and after that its faster
First call in node 11.14.0:
loop: 270.822ms
map: 1293.307ms
Next calls in node 11.14.0:
loop: 366.816ms
map: 259.317ms
undefined

test()
loop: 304.949ms
map: 76.464ms
undefined
test()
loop: 290.823ms
map: 76.344ms
undefined
test()
loop: 293.326ms
map: 73.094ms
undefined
test()
loop: 288.508ms
map: 77.012ms

In chrome i dont get any notable performance hit by using map instead of loop with these code.

Collapse
 
henryjw profile image
Henry Williams

That's interesting. I going to try that.

Collapse
 
dimon4eg profile image
Dimon4eg

You can also speed up for loop: allocate array with 1M elements and in for loop assign values.

Collapse
 
joshualjohnson profile image
Joshua Johnson

Makes since, array.map calls a callback in a loop, then it's got to coordinate the callback with finishing its execution before it can move on to calling the callback again.

Them more code executions you have to do at the machine level, the slower the code will run.

Collapse
 
motss profile image
Rong Sen Ng

Alternatively, for...of loop is another thing you should look into rather than conventional for loop.

Collapse
 
latchy profile image
Ben Latchford

Well if you consider the map acting as a function on each element, it's also having to create a new stack frame for each iteration.. a lot slower.