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.