I have been working on a real-time application where every micro-optimization matters. In this post I will explain how I optimized my loops for performance while keeping readibility just as important.
You should always write youre source code to be easily readable and maintainable. While ES6 functions like .forEach, .map, .filter and statements like for..of and for..in increase readibility in many cases, they decrease runtime speed at the same time. So instead of choosing one over the other, choose both using a transpiler.
Performance in numbers
You can find a bunch of JavaScript performance tests on jsperf.com or you can write your own even. There are several tests about this topic, see my comparison.
forEach | randomStrings.forEach(val => randomStringsCopy.push(val)); | 1,666 ±7.23% 44% slower |
for..in | for(let i in randomStrings){ randomStringsCopy.push(randomStrings[i]); } | 1,356 ±3.52% 52% slower |
for..of | for (let randomString of randomStrings){ randomStringsCopy.push(randomString); } | 2,877 ±4.46% fastest |
for loop, reverse, pre-decrement | for(let i = randomStrings.length – 1; i >= 0; –i){ randomStringsCopy.push(randomStrings[i]); } | 2,672 ±11.24% fastest |
In a later post I might write a more in-depth answer why all this happens, until then, use a transpiler like Babel so you do not have to rewrite your source code to a less readeble one for micro optimization.
Use a transpiler
There are two Babel plugins to transpile .forEach, .map, .filter functions and statements like for-of and for-in to the fastest one.
If you use Babel, just add the following two plugin in your .babelrc configuration file:
Unfortunately, the second plugin is unmaintained and neither of them transpiles to reversed index based loops. One could publish a plugin that solves all of this in one place.
Conclusion
Nowadays less and less people care about performance and optimization but there are cases where this is critical. Even though you want your application to run as fast as possible, you should write your source code to be maintainable and readibility is a key aspect of that. For this reason, new functions like .forEach, .map, .filter and for..of are useful but make sure to transpile them using bundler tools.