4

As my research leads me to believe that for loops are the fastest iteration construct in javascript language. I was thinking that also declaring a conditional length value for the for loop would be faster... to make it clearer, which of the following do you think would be faster?

Example ONE

for(var i = 0; i < myLargeArray.length; i++ ) {
    console.log(myLargeArray[i]);
} 

Example TWO

var count = myLargeArray.length;
for(var i = 0; i < count; i++ ) {
    console.log(myLargeArray[i]);
} 

my logic follows that on each iteration in example one accessing the length of myLargeArray on each iteration is more computationally expensive then accessing a simple integer value as in example two?

AndrewMcLagan
  • 13,459
  • 23
  • 91
  • 158
  • 3
    Have you tried writing a performance test? – Spoike Oct 09 '12 at 09:29
  • no, there is always so much controversy surrounding such test and their parameters... – AndrewMcLagan Oct 09 '12 at 09:30
  • 2
    You basically answered yourself. It highly depends on the conditions, so it's basically untestable. And you provided a specific example, you can actually test that specific example. – Dykam Oct 09 '12 at 09:30

5 Answers5

7

Contrary to some of the statements below, the length of an Array is not calculated on each iteration. The length of an Array is a property which is set by modifying operations such as pop, push, shift, unshift, splice and so forth.

You will see a minor performance hit though since a property lookup has a higher cost than a local variable. Therefore caching the length is a good idea. However you won't see a big difference unless you are dealing with huge datasets.

There is a special case though where the length is indeed calculated on each iteration. This is the case with HTML node collections. Since these are live objects, the length is not a property in the sense it is with an array. If you do this:

for (var i=0; i < collection.length; i++) {
    collection[i]
};

Then the collection is parsed on each iteration.

As for optimizing a for loop, I usually use these techniques for caching:

// if order is of no concern, just iterate from length-1 to 0
for (var i = arr.length - 1; i >= 0; i--){
    arr[i]
};

// use the for loop statement to set up scoped variables
for (var i=0, length = arr.length; i < length; i++) {
    // do something
}
AndrewMcLagan
  • 13,459
  • 23
  • 91
  • 158
Torsten Walter
  • 5,614
  • 23
  • 26
4

From JavaScript Garden, a great resource on the quirks of JavaScript.

Although the length property is defined on the array itself, there is still an overhead for doing the lookup on each iteration of the loop. And while recent JavaScript engines may apply optimization in this case, there is no way of telling whether the code will run on one of these newer engines or not.

Johanna Larsson
  • 10,531
  • 6
  • 39
  • 50
  • I just did a quick dirty test in chrome and it had exactly the same result for both loops, that is for the exact code above, considering myLargeArray is 1000 elements long – AndrewMcLagan Oct 09 '12 at 09:43
1

I don't think you have anything to lose by going with the second version every time, although I would be surprised if the array length actually got calculated from scratch each time with the first approach unless the array actually gets mutated by the loop.

Don't forget that you can declare more than one variable in the first part of the for:

for(var i = 0, count = myLargeArray.length; i < count; i++ ) {
    console.log(myLargeArray[i]);
}
codebox
  • 19,927
  • 9
  • 63
  • 81
1

From High Performance JavaScript

Decreasing the work per iteration:

//original loops
for (var i=0; i < items.length; i++){
process(items[i]);
}

var j=0;
while (j < items.length){
process(items[j++]]);
}

var k=0;
do {
process(items[k++]);
} while (k < items.length);



//minimizing property lookups
for (var i=0, len=items.length; i < len; i++){
process(items[i]);
}

var j=0,
count = items.length;
while (j < count){
process(items[j++]]);
}

var k=0,
num = items.length;
do {
process(items[k++]);
} while (k < num);


//minimizing property lookups and reversing
for (var i=items.length; i--; ){
process(items[i]);
}

var j = items.length;
while (j--){
process(items[j]]);
}

var k = items.length-1;
do {
process(items[k]);
} while (k--);

Decreasing the number of iterations:

//credit: Jeff Greenberg
var i = items.length % 8;
while(i){
process(items[i--]);
}
i = Math.floor(items.length / 8);
while(i){
process(items[i--]);
process(items[i--]);
process(items[i--]);
process(items[i--]);
process(items[i--]);
process(items[i--]);
process(items[i--]);
process(items[i--]);
}

See JavaScript Optimization

chris
  • 1,245
  • 1
  • 10
  • 22
  • Just to mention approach "//minimizing property lookups and reversing" is good if the order is not important – GibboK Jan 28 '15 at 14:48
0

Yes you are right myLargeArray.length is being calculate in each iteration of loop ( first example). link1 link2

for(var i = 0; i < myLargeArray.length; i++ ) {
    console.log(myLargeArray[i]); 
} 
Community
  • 1
  • 1
Anoop
  • 23,044
  • 10
  • 62
  • 76
  • Note length is not calculated when looking it up, it is changed when adding or removing items (simply increase or decrease), so that is not a performance difference for the OP. – Dykam Oct 09 '12 at 09:32
  • 1
    @Dykam I think reading length of an array and then comparing is more computationally than directly comparing with integer. – Anoop Oct 09 '12 at 09:34
  • Your answer changed. Before it was about computing the length of the array. My comment is now irrelevant. – Dykam Oct 09 '12 at 11:19
  • @Dykam Sorry, I have to remove that since it was adding additional computation due to Array.pop(); – Anoop Oct 09 '12 at 11:21