For loop performance improvement

For loop performance improvement
0

#1

I came across this suggestion and wanted to share it as nobody seems to do this.

Bad:

var i;
for (i = 0; i < arr.length; i++) {

Better Code:

var i;
var l = arr.length;
for (i = 0; i < l; i++) {

As suggested here: http://www.w3schools.com/js/js_performance.asp


#2

Oh, that’s why we loved W3Schools…

Nobody seems to do this because:

  • Programmers don’t waste their time optimising things that don’t need to be optimised
  • It doesn’t worth sacrificing readability for such a small improvement (if any)

I.e. iterating through an array with 1,000 elements vs 10,000,000 elements have only a few ms difference.

If you check the link above and run it in your browser, you’ll see similar results:

Length in for statement (small array): 0.2ms
Length in for statement (large array): 17ms
Length in variable (small array): 0ms
Length in variable (large array): 14.8ms

Length in for statement (small array): 0ms
Length in for statement (large array): 15.6ms
Length in variable (small array): 0ms
Length in variable (large array): 18.8ms

Length in for statement (small array): 0ms
Length in for statement (large array): 17.4ms
Length in variable (small array): 0ms
Length in variable (large array): 14.4ms

Length in for statement (small array): 0ms
Length in for statement (large array): 15ms
Length in variable (small array): 0ms
Length in variable (large array): 15.2ms

As you can see there is no real difference on an array with 10k elements. And if you check the results for larger arrays, sometimes it can be even faster to iterate through the 10 million elements accessing the array’s length from the for loop.


#3

Is this because arr.length is a non enumerable property, and so it doesn’t actually have to count the length when accessed - so in effect should only take the same amount of time as accessing a variable?

Not trying to be a smart arse and prove anyone right or wrong - just checking my understanding :slight_smile:


#5
for (let i = arr.length; i--; ) {

is also an option if one doesn’t care about iteration order.


#6

But aren’t variables declared with let in a for loop’s header redeclared per iteration? Wouldn’t that have an effect on performance?


#8

I asked that because this was in YDKJS:

There’s a special behavior defined for let declarations used in the head of a for-loop. This behavior says that the variable will be declared not just once for the loop, but each iteration.

It was bugging me (and I’d probably have trouble falling asleep) so I tried this:

const arr = [10, 20, 30, 40, 50];
function length() {
    console.log('I\'ve been called');
    return arr.length;
}

for (let i = 0, len = length(); i < len; i++) {
    console.log(arr[i]);
}

And you’re right! The length() function was only called once.

I've been called
10
20
30
40
50

#9

Personally I don’t think it’s a waste of time. Plus now I know there is an optimisation possible, I will be in the habit of making this optimisation in future.

But thanks for taking the time to prove W3Schools wrong.


#10

That’s interesting.

at each iteration, a new scope is created ?(with its own i) :

for(let i = 0; i < 5; i++) {
    setTimeout(function(){
        console.log(i);    // logs 0,1,2,3,4
        // the use of var would log 5,5,5,5,5
    }, i * 1000);
}

But if we modify the value of i within each iteration/scope, it implicitely affects the for loop’s i


for(let i = 0; i < 5; i++) {
    i++; // line added
    setTimeout(function(){
        console.log(i);    // logs 1,3,5
        // and not 1,2,3,4,5
    }, i * 1000);
}