views:

85

answers:

7

In the following code:

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

does the operation object.length get evaluated every time in the iteration?
It would make most sense that the language will evaluate this once and save the result. However, I was reading some code where someone evaluated the operation before the loop started and stored it in a variable that was used in the end-condition.
Do different languages handle this differently? Any specific info for Javascript?

+3  A: 

Completely depends on the language and (possibly) on what's in the loop. The compiler/interpreter may or may not be able to determine with certainty that the "length" property won't be changed by something in the loop.

In Javascript, it's a safe bet that it'll be re-evaluated. A simple property reference like that probably isn't that bad, but something like a function call could be a performance problem. edit To clarify, by "a function call" I mean code of any form that computes the loop termination condition in any way expensive enough to make you feel bad about doing it on each iteration.

Thus (pardon my jQuery),

for (var i = 0; i < $('.foo').length; ++i) { /* ... */ }

would involve a traversal of the whole DOM on each iteration.

Pointy
Function calls themselves don't correlate directly with performance problems, in dynamic languages; function bodies could be inlined in, for example.
Chris Jester-Young
And a "simple property reference" could be calling a complex getter function (though it should be simple in this case).
Matthew Flaschen
@Chris - oh yes; what I should have said was "function calls that do a lot of work". I can clarify.
Pointy
@Pointy: Nice change. :-) Too bad I can't upvote you twice!
Chris Jester-Young
Another example (using prompt instead of jQuery): for (var i=0; i<parseInt(prompt("Max I?")); i++) { console.log("Hello "+i); }
Roy Tinker
+2  A: 

The condition has to be re-evaluated at each iteration of the loop because in theory the value could have changed inside the loop body.

Mark Byers
+6  A: 

It obviously depends on the language. For JavaScript, the spec (ECMAScript §12.6.3) requires it always be evaluated each time. As an optimization, a specific JavaScript runtime could skip one or more of the length calls, if it could prove that the result would not change.

Matthew Flaschen
A: 

In Javascript it does get evaluated every time. You can get around it by setting a "max" variable in the first part of the loop:

for (var i=0, imax=object.length; i<imax; i++) {
  // statements
}
Robusto
+1  A: 

In some languages this depends on the level of optimization you have configured at build-time. I believe in C++, for example, marking a field as volatile will force re-evaluation. Check out these links:

http://en.wikipedia.org/wiki/Loop_unwinding

http://msdn.microsoft.com/en-us/library/12a04hfd.aspx

Alex
A: 

Yes it gets calculated each iteration ..

why not test it ?

var loop = 5;

for (var i = 0; i< loop; i++)
    {
    alert(i + ' of ' + loop);
    loop--;
    }

live at http://jsfiddle.net/MSAdF/

Gaby
+2  A: 

A smart compiler could automatically optimize for this case, but performing static analysis to determine that the length will not change inside the loop is extremely difficult in JavaScript. For this reason, you can say that in most cases object.length will indeed be reevaluated in each iteration.

On the other hand, it's often simpler for the programmer to reason out that the length will certainly not change, and if you're really (I mean, really) worried about performance, you could pre-compute and store the length before the loop starts.

casablanca