-1

I was reading the book Eloquent Javascript and the writer of the book Marjin Haverbeke noted that built in function calls run slower than a regular for or while loop but why is that?

Edit: this question his related to this one and is also helpful regarding this one.

Salman Sarray
  • 949
  • 8
  • 11
  • Possible duplicate of [Javascript efficiency: 'for' vs 'forEach'](https://stackoverflow.com/questions/43031988/javascript-efficiency-for-vs-foreach) – gforce301 Apr 06 '18 at 16:13
  • There are a ton of dups of this as this has been discussed many, many times. I know I've seen at least 5 other questions/answers like this, but I can't seem to find a good one right now to mark a dup. There was even one just yesterday. Sometimes hard to find things in stack overflow search though. – jfriend00 Apr 06 '18 at 16:26
  • not really they are completely different – Salman Sarray Apr 06 '18 at 16:42
  • @jfriend00 It's certainly because there is no absolute answer, as (from what we can read on SO and other sites) it depends of your environment and of the datas you have to deal with. – scraaappy Apr 06 '18 at 16:45
  • @scraaappy - Modern JS engines have optimized the `for` loop so it's pretty much always faster than a `.forEach()` loop because the `.forEach()` loop has the overhead of a function call and a function scope object on every single iteration of the loop, whereas a `for` loop doesn't. I don't think this is dependent upon the environment any more. `.map()` serves a different purpose than a plain `for` loop (it creates a new array) so it has a different function. You could reimplement yourself in a `for` loop if you want, but usually that's just wasted code vs. using what already works. – jfriend00 Apr 06 '18 at 16:49
  • Sorry I was not precise enough in my comment, and I isolate one part of the question. I was considering rather map vs for loop. In some scenarios, map is much more efficient than for loops. So if we make performance measurements with @T.J.Crowder 's provided code: http://jsben.ch/7F5b2 This is more probant with nested arrays and nested loops : http://jsben.ch/rlsET (although nested arrays have fixed length) That's what I wanted to point out. – scraaappy Apr 08 '18 at 13:06

1 Answers1

6

The ones you listed (map, forEach) call functions. So compare

const updated = original.map(e => e * 2);

to

const updated = [];
let i; // (Declaring these here is a premature micro-optimization¹ for effect)
const len = original.length;
for (i = 0; i < len; ++i) {
    updated[i] = original[i] * 2;
}

For a 100-entry array, the first example has all the overhead of the second example plus the overhead of creating the function, the overhead of the call to map, and the overhead of 100 calls to the callback. Of course it's slower in absolute terms. That's provided the JavaScript engine can't optimize-away the calls, of course. If the callback is trivial, the engine can optimize it if it identifies it as a slow point in the code. scraaappy put together this benchmark, which for me at least shows Chrome and Firefox optimizing the map to be faster than the for, while Edge doesn't (which surprised me somewhat, the Chakra engine in Edge is very good). (I wouldn't be surprised if IE11 didn't either, but that benchmark site doesn't appear to work with IE11.)

Does it matter in practice? Almost never. Function calls in modern JavaScript engines are extremely fast.

Write what's clear to you (without being really silly). Optimize if and when you have a problem with performance. :-)


¹ What's the premature micro-optimization? If I'd declared i in the for, like this:

const updated = [];
for (let i = 0, len = original.length; i < len; ++i) {
    updated[i] = original[i] * 2;
}

...a different i gets created for each loop iteration (so closures created in the loop can close over each of them and not have the closures-in-loops problem).

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • So, the question is about performance, but you offer zero performance measurements in your answer? Plus, aren't there a ton of dups of this? – jfriend00 Apr 06 '18 at 16:55
  • 1
    @jfriend00: I don't think measurements are necessary for this question, not least because presumably Haverbeke has demonstrated the claim in the book. And [like you](https://stackoverflow.com/questions/49696940/why-are-built-in-function-calls-like-map-foreach-etc-slower-than-a-regular/49697096?noredirect=1#comment86407297_49696940), I couldn't find a good dupe, though like you, I find it hard to believe there isn't one. :-) (A good one, I mean.) – T.J. Crowder Apr 06 '18 at 16:59
  • 1
    @scraaappy: Yeah, I should have commented on optimization (and now I have). JavaScript engines can optimize away the function calls for trivial examples (like mine above). With your benchmark, for instance, Chrome does, Firefox does, Edge doesn't (or at least, not enough to make it faster than the `for` loop). – T.J. Crowder Apr 08 '18 at 13:15