views:

63

answers:

5

Consider the following 2 scenarios:

boolean b = false;
int i = 0;
while(i++ < 5) {
    b = true;
}

OR

boolean b = false;
int i = 0;
while(i++ < 5) {
    if(!b) {
        b = true;
    }
}

Which is more "costly" to do? If the answer depends on used language/compiler, please provide. My main programming language is Java.

Please do not ask questions like why would I want to do either.. They're just barebone examples that point out the relevant: should a variable be set the same value in a loop over and over again or should it be tested on every loop that it holds a value needed to change?

+1  A: 

Are you trying to find out if doing the assignment each loop is faster in total run time than doing a check each loop and only assigning once on satisfaction of the test condition?

In the above example I would guess that the first is faster. You perform 5 assignments. In the latter you perform 5 test and then an assignment.

But you'll need to up the iteration count and throw in some stopwatch timers to know for sure.

MattC
A: 

Any compiler (except, perhaps, in debug) will optimize both these statements to

bool b = true;

But generally, relative speed of assignment and branch depend on processor architecture, and not on compiler. A modern, super-scalar processor perform horribly on branches. A simple micro-controller uses roughly the same number of cycles per any instruction.

ruslik
A: 

Relative to your barebones example (and perhaps your real application):

boolean b = false;
// .. other stuff, might change b
int i = 0;
// .. other stuff, might change i
b |= i < 5;
while(i++ < 5) {
    // .. stuff with i, possibly stuff with b, but no assignment to b
}

problem solved?

But really - it's going to be a question of the cost of your test (generally more than just if (boolean)) and the cost of your assignment (generally more than just primitive = x). If the test/assignment is expensive or your loop is long enough or you have high enough performance demands, you might want to break it into two parts - but all of those criteria require that you test how things perform. Of course, if your requirements are more demanding (say, b can flip back and forth), you might require a more complex solution.

Carl
A: 

Have you tested this? Working on a Linux system, I put your first example in a file called LoopTestNoIf.java and your second in a file called LoopTestWithIf.java, wrapped a main function and class around each of them, compiled, and then ran with this bash script:

#!/bin/bash
function run_test {
  iter=0
  while [ $iter -lt 100 ]
  do
    java $1
    let iter=iter+1
  done
}
time run_test LoopTestNoIf
time run_test LoopTestWithIf

The results were:

real    0m10.358s 
user    0m4.349s 
sys     0m1.159s 

real    0m10.339s
user    0m4.299s 
sys     0m1.178s

Showing that having the if makes it slight faster on my system.

GreenMatt
A: 

Please do not forget the rules of Optimization Club.

  1. The first rule of Optimization Club is, you do not Optimize.
  2. The second rule of Optimization Club is, you do not Optimize without measuring.
  3. If your app is running faster than the underlying transport protocol, the optimization is over.
  4. One factor at a time.
  5. No marketroids, no marketroid schedules.
  6. Testing will go on as long as it has to.
  7. If this is your first night at Optimization Club, you have to write a test case.

It seems that you have broken rule 2. You have no measurement. If you really want to know, you'll answer the question yourself by setting up a test that runs scenario A against scenario B and finds the answer. There are so many differences between different environments, we can't answer.

Andy Lester