3

So let's consider the case where there is the below snippet:

if(x == 0)
{
     for(var i = 0; i < 5; ++ i)
     {
         //do something  
     }
}
else
{
   for(var i = 0; i < 5; ++ i)
     {
         //do something different
     }
}

As you can see, both of the conditions iterate through the same for loop but perform different actions based on the condition. My question is, is it a bad practice to have something like this:

for(var i = 0; i < 5; ++ i)
{
     if(x == 0){
       // do something
     }else{
        // do something else
     }
}

The reason being that I think that this may be a bad practice is due to the fact that for every instance of the loop, a conditional check is being executed on it against the first snippet where he condition is checked first and then the loop is executed. Am I mistaken?

David
  • 1,192
  • 5
  • 13
  • 30

2 Answers2

5

Unless you're writing code that must run at high speed and be super efficient, go for code readability over efficiency. In this case, I'd say the 2nd example is clearer as it's less code, and a commonly followed pattern.

I suppose another factor to consider though is that the 2nd example seems to imply that x might change value, whereas the 1st example doesn't. This would be worth putting a comment nearby explaining the choice.

My gut instinct would agree with you, that the 1st example would be more efficient, but in reality the compiler's optimisations are likely to make short work of examples like the above - they'll both likely be equal in performance.

Here's a pretty impressive list of optimisations that can be made on loops, to give you an idea, and also branch optimisation (see the answer), may have an effect if the loops run for many iterations.

hnefatl
  • 5,860
  • 2
  • 27
  • 49
  • It would be better if you gave examples of other cases like long loops or loops in loops cases. Result would be very different with these cases. – ReadyFreddy Jul 25 '17 at 08:22
  • 1
    @ReadyFreddy I don't know enough about compiler optimisations to provide good examples - I'll add a few links to resources that seem relevant though, good point. Feel free to edit my answer if you can add examples though. – hnefatl Jul 25 '17 at 08:24
  • 1
    @hnefatl: Indeed. The first variant is typically preferable when optimizing for speed and the second where optimizing for size. Beware that relying on the automatic hosting by the optimizer is brittle though if used on a critical code path, since proving whether or not `x` may change through aliasing or the like is non-trivial in the general case. A local copy may be a helpful hint, but of course then it conversely falls upon the programmer to prove that `x` is constant. – doynax Jul 25 '17 at 08:31
0

If you use

if(x = 0)
{
     for(var i = 0; i < 5; ++ i)
     {
         //do something  
     }
}
else
{
   for(var i = 0; i < 5; ++ i)
     {
         //do something different
     }
}

then you have done one comparison and a loop performing the tasks in the scope for 5 times.

When you use

for(var i =0; i < 5; ++ i)
{
     if(x = 0){
       // do something
     }else{
        // do something else
     }
}

then a loop performing the tasks in the scope for 5 times. In addition to that, the comparison is done 5 times.

On first sight the former results in least amount of instructions. But the compiler/interpreter may perform an optimization step by doing that comparison one time. But this depend of the compiler/interpreter. If you have a good comprehending of how a compiler/interpreter works for a given language you're programming on, you can "abuse" the knowledge to write a readable code and yet having a well-optimized output.

Yet, another alternative is to work with functions. This approach is only useful if the variable x is constant throughout the loop, with other words: you don't modify it during the loop itself. This is the case at your first example. However, in the second example: x can be changed in the loop, which leads to running either the if {} or else{} block during the loop, executing two different functions.

Alternative: Select a function first and use it in the loop. It may be more useful if you have lots of different tasks to perform. Just select a function beforehand. Some programming languages allows this, another don't. So it depends of the language itself.

// check which function to run
variable runThisFunction;
if (x = 0) runThisFunction = { // do something }
else runThisFunction = { // do something else }

// loop 5 times using the function
for(var i =0; i < 5; ++ i)
{
     call runThisFunction with arg i provided.
}
KarelG
  • 5,176
  • 4
  • 33
  • 49
  • It's also worth noticing that those aren't equivalent if there's a chance either `do something` or `do something else` change the value of `x`. – Jordi Nebot Jul 25 '17 at 08:32
  • (An this always assuming OP really means `x == 0` instead of `x = 0`) – Jordi Nebot Jul 25 '17 at 08:34
  • 1
    @JordiNebot true, but if you look to the first example, you can see that he tries to select a task and then do it 5 times. Ofc it may differ in the second example which `x` can be altered. If it's altered, then my example is ofc not valid. Gotcha edit the post – KarelG Jul 25 '17 at 08:34