5

Imagine a really simple task that requires a tight loop, like summing up the values of an array. I wrote 5 different codes to achieve that:

const arr = Array(1000000).fill(0).map(() => Math.random());

// 1: (ab)using .forEach
let x1 = 0;
arr.forEach((i) => x1 += i);

// 2. using reduce
let x2 = arr.reduce((a, n) => a + n, 0);

// 3: classic forward for-loop
let x3 = 0;
for(let i = 0; i < arr.length; i++)
    x3 += arr[i];

// 4: backward for-loop, should be faster, because comparison with a literal is faster
let x4 = 0;
for(let i = arr.length - 1; i >= 0; i--)
    x4 += arr[i];

// 5: backward while-loop, should be fastest, because it combines comparison and decrement
let x5 = 0;
let i = arr.length;

while(i--)
    x5 += arr[i];

I usually use either the first or second version, because in most loops readability is more important than performance. However, for fun I benchmarked this. The results vary sligthly with each run, but on Chrome 90.0.4430.95 I see this trend:

  • Versions 1 and 2 are the slowest by a huge margin (expected)
  • Version 3, 4 and 5 almost equally fast, however
    • 5 is almost never the fastest (suprising!)
    • Most of the time 3 is the fastest by a slight margin compared to 4 (suprising, but could be due to inaccuracies in the meassurement)

Why is that? Is it just inaccuracy of the benchmark? Then why would 5 almost never be the fastest? Does my Browser optimize the forward for-loop?

I'd like to emphasise that is a purely theoretical question and that in real code I don't care about such micro optimizations.

Here some reference questions that I've read:

JavaScript loop performance - Why is to decrement the iterator toward 0 faster than incrementing - from this I expected backward-for to be faster then forward-for.

Javascript Performance: While vs For Loops - from this I expected backward-while to be even faster than backward-for.

Both questions are a bit older, so they might as well be outdated, because of better browser support.

Lukas-T
  • 11,133
  • 3
  • 20
  • 30
  • 5
    "*Does my Browser optimize the forward for-loop?*" - yes. Idiomatic code is optimised best. – Bergi Jun 23 '21 at 08:49
  • 3
    also - different browsers *may* have different results as far as which is fastest/slowest -also, my chrome almost always has 5 as fastest – Jaromanda X Jun 23 '21 at 08:55
  • If you would have created a snippet, everybody would be able to test it. – ceving Jun 23 '21 at 08:56
  • 2
    @ceving - there's a link to a benchmark in the question that you can run http://jsbench.github.io/#1ae27c770d9ca5eed80fafe88ddf72ff - I'd trust jsbench over a snippet any day – Jaromanda X Jun 23 '21 at 08:57
  • @ceving What exactly do you mean? I've posted the full code and a link to the benchmark. – Lukas-T Jun 23 '21 at 08:58
  • 3
    @Bergi If that's the whole reason I would happily accept this as an answer. Mainly because it would disprove my co-workers need to write unreadable and often error-prone reverse for-loops ;) – Lukas-T Jun 23 '21 at 09:00

0 Answers0