Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chrome for loop optimization

So I was curious what would be faster for iterating through an array, the normal for loop or forEach so I executed this code in the console:

var arr = [];
arr.length = 10000000;
//arr.fill(1);
for (var i_1 = 0; i_1 < arr.length; i_1++) {
arr[i_1] = 1;
}
//////////////////////////////////
var t = new Date();
var sum = 0;
for (var i = 0; i < arr.length; i++) {
    var a = arr[i];
    if (a & 1) {
        sum += a;
    }
    else {
        sum -= a;
    }
}
console.log(new Date().getTime() - t.getTime());
console.log(sum);

t = new Date();
sum = 0;
arr.forEach(function (value, i, aray) {
    var a = value;
    if (a & 1) {
        sum += a;
    }
    else {
        sum -= a;
    }
});
console.log(new Date().getTime() - t.getTime());
console.log(sum);

Now the results in Chrome are 49ms for the for loop, 376ms for the forEach loop. Which is ok but the results in Firefox and IE (and Edge) are a lot different.

In both other browsers the first loop takes ~15 seconds (yes seconds) while the forEach takes "only" ~4 seconds.

My question is can someone tell me the exact reason Chrome is so much faster?

I tried all kinds of operations inside the loops, the results were always in favor for Chrome by a mile.

like image 598
chnging Avatar asked Mar 10 '17 13:03

chnging


1 Answers

Disclaimer: I do not know the specifics of V8 in Chrome or the interpreter of Firefox / Edge, but there are some very general insights. Since V8 compiles Javascript to native code, let's see what it potentially could do:

  • Very crudely: variables like your var i can be modelled as a very general Javascript variable, so that it can take any type of value from numbers to objects (modelled as a pointer to a struct Variable for instance), or the compiler can deduce the actual type (say an int in C++ for instance) from your JS and compile it like that. The latter uses less memory, exploits caching, uses less indirection, and can potentially be as fast as a for-loop in C++. V8 probably does this.
  • The above holds for your array as well: maybe it compiles to a memory efficient array of ints stored contiguously in memory; maybe it is an array of pointers to general objects.
  • Temporary variables can be removed.
  • The second loop could be optimized by inlining the function call, maybe this is done, maybe it isn't.

The point being: all JS interpreters / compilers can potentially exploit these optimizations. This depends on a lot of factors: the trade-off between compilation and execution time, the way JS is written, etc.

V8 seems to optimize a lot, Firefox / Edge maybe don't in this example. Knowing why precisely requires in-depth understanding of the interpreter / compiler.

like image 67
Harmen Avatar answered Sep 21 '22 20:09

Harmen