Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Which style is best when you have a for loop with an unused control variable and a computationally expensive termination condition?

The number of iterations is important, but the control variable (n) is not used within the loop.

//1
for(int n=0; n</*termination condition*/; n++) {
 //do something
}

//2
int limit = //termination condition
for(int n=0; n<limit; n++) {
 //do something
}

//3
for(int n=/*termination condition*/; n>0; n--) {
 //do something
}

Option 1 will cause the condition to be evaluated on each iteration of the for loop, which is not performant.

I tend to use option 2, since it is performant and explicit.

Option 3 is performant and concise.

share|improve this question
5  
Traditional C-style for loops are one of the most over-used (and badly used) constructs in all the languages which support them, to the extent that I see them as a code smell. It's always worth re-examining your code to see if you couldn't do the job better with something else, particularly in an OO language (in Java, this often involves generics). I'd check that first before worrying about this issue. –  itsbruce Oct 15 '13 at 10:44
1  
it sounds like the code is heavily dependent on side-effects (if n not used), my first step would probably to look at if I can simplify the code by making the side effects explicit or removing them. –  jk. Oct 15 '13 at 11:40
1  
Wouldn't an optimizing C compiler turn option 1 into 2? So you get the best of all worlds: clarity, conciseness and performance? (I'm assuming termination condition is constant within the loop, of course) –  Andres F. Oct 15 '13 at 12:34
    
@AndresF. This is Java, as it happens, so maybe. The optimisation is known as "Loop Invariant Code Motion". In the Java world, almost no aggressive optimisation (including this kind) is done at the compile-to-bytecode stage - it's left for JIT compilers to do, in the hope that they can pick the optimisation method most appropriate to the native hardware. –  itsbruce Oct 15 '13 at 12:53
    
@itsbruce Oops, I misread the example as C. I know about the JIT, but I thought it was C. Disregard my comment! –  Andres F. Oct 15 '13 at 13:03
show 1 more comment

closed as primarily opinion-based by gnat, jk., Ozz, GlenH7, MichaelT Oct 16 '13 at 1:44

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise.If this question can be reworded to fit the rules in the help center, please edit the question.

2 Answers

to be certain, option 2, however I'd probably actually use option 1 unless profiling says it's a problem, as there is a very good chance these will be optimized to the same thing anyway.

option 3 is, of course, not equivalent

  • it loops in a different order
  • it ranges between 1 and termination_condition rather than 0 and termination_condition - 1

(this may be a mistake in your question, but this demonstrates why we usually don't loop backwards, it's harder to get the fence posts in the right place)

If you are only interested in the number of times the loop runs I'd still avoid 3 just as backward loops are less often used so more likely to confuse a reader.

share|improve this answer
    
Since the control variable is used then the non-equivalence of option 3 is not a problem. I'll edit the question to make it clearer. Good tip about the profiling. –  user2882061 Oct 15 '13 at 10:58
1  
@user2882061: With 3, even though it is equivalent in this case, its less readable and maintainable. Typically programmers only use backwards loops when backward loops are needed. If you use a backwards loop, I need to study the code harder, as I will suspect there is a reason for it. When I find no reason for it, I will add it to my weekly WTF's –  mattnz Oct 15 '13 at 20:35
add comment

Option 4, proposed for completeness:

for(int n=0, limit = /* messy expression */; n < limit; n++) {
   do something;
}

Personally, I'd go with Option 2.

Added later:

Option 1 can only be optimized to Option 2 if the compiler can prove to its own satisfaction that the messy expression is invariant. If the expression does any calls to external functions, or references any externally-visible "stuff", especially stuff marked "volatile", the compiler will not be able to prove the invariance, and hence will not do the optimization. You as the programmer might know it is invariant, in which case it is your job to tell the compiler that. You can most easily do that by writing Option 2 or Option 4, as opposed to writing Option 1.

share|improve this answer
    
-1: Its unnatural - Most guides to writing maintainable code restrict or ban using ',' in for loops. –  mattnz Oct 15 '13 at 20:42
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.