views:

541

answers:

9

Hay Dear!

i know that if statement is an expensive statement in c++. I remember that once my teacher said that if statement is an expensive statement in the sense of computer time.

Now we can do every thing by using if statement in c++ so this is very powerful statement in programming perspective but its expensive in computer time perspective.

i am a beginner and i am studying data structure course after introduction to c++ course. my Question to you is
Is it better for me to use if statement extensivly?

+6  A: 

I would say a lot of if statement is expensive from the maintainability perspective.

Mykola Golubyev
+9  A: 

I'm not sure how you can generalise that the if statement is expensive.

If you have

if ( true ) { ... }

then this the if will most likele be optimised away by your compiler.

If, on the other hand, you have..

if ( veryConvolutedMethodTogGetAnswer() ) { .. }

and the method veryConvolutedMethodTogGetAnswer() does lots of work then, you could argue tha this is an expensive if statement but not because of the if, but because of the work you're doing in the decision making process.

"if"'s themselves are not usually "expensive" in terms of clock cycles.

ScaryAardvark
+2  A: 

You should write your code to be correct, easy to understand, and easy to maintain. If that means using if statements, use them! I would find it hard to believe that someone suggested you to not use the if statement.

Maybe your instructor meant that you should avoid something like this:

if (i == 0) {
    ...
} else if (i == 1) {
    ...
} else if (i == 2) {
    ...
} ...

In that case, it might be more logical to rethink your data structure and/or algorithm, or at the very least, use switch/case:

switch (i) {
    case 1: ...; break;
    case 2: ...; break;
    ...;
    default: ...; break;
}

But even then, the above is better more because of improved readability rather than efficiency. If you really need efficiency, things such as eliminating if conditions are probably a bad way to start. You should profile your code instead, and find out where the bottleneck is.

Short answer: use if if and only if it makes sense!

Alok
A: 

In terms of computer time the "if" statement by itself is one of the cheapest statements there is.

Just don't put twenty of them in a row when there is a better way like a switch or a hash table, and you'll do fine.

RobC
I find this dubious. There /is/ a cost to a conditional branch, and it exceeds (for example) basic integer arithmetic.
Matthew Flaschen
Yes, basic integer arithmetic is faster at 0.2ns for a typical processor nowadays, but "if" is almost as fast - typically 0.5ns on average, and most operations such as method calls run into the hundreds of nanoseconds. I stand by my claim that "if" is **one of** the cheapest statements there is.
RobC
+14  A: 

If statements are compiled into a conditional branch. This means the processor must jump (or not) to another line of code, depending on a condition. In a simple processor, this can cause a pipeline stall, which in layman's terms means the processor has to throw away work it did early, which wastes time on the assembly line. However, modern processors use branch prediction to avoid stalls, so if statements become less costly.

In summary, yes they can be expensive. No, you generally shouldn't worry about it. But Mykola brings up a separate (though equally valid) point. Polymorphic code is often preferable (for maintainability) to if or case statements

Matthew Flaschen
Totally agree. Polymorphism rocks :)
ScaryAardvark
Matthew just for clarification if jump is made very close to current executing instruction which expected to be present in cache as well. will that make if still expensive. Most of if jump to few instruction away. And second a function call might result in more wast of time than a if instruction since a function call require saving of stack passing parameter and than jumping to another location may be far away.
affan
If you are jumping to a nearby line, it may be in instruction cache. But if the processor predicts wrong, there could still be a pipeline stall. And the branch prediction logic itself is part of the true cost. A function call is also costly.
Matthew Flaschen
Note that the proposed polymorphic code is even worse than conditional branches. With conditional branches, the CPU guesses. With polymorphic code, the CPU pipeline just stalls.
MSalters
Branch prediction isn't going to happen with the v-tables you need for polymorphism. It could be a worse choice but C++ offers methods to remedy this with templates. I start to think about using polymorphism as soon as I use case statements not when I use a single if.
pmr
I meant that polymorphic code is often more maintainable than a long series of if or switch/case statements, not that it performed better and certainly not that all ifs should be replaced with polymorphic code.
Matthew Flaschen
"not that all ifs should be replaced". Where's the fun in that? If a thing's worth doing, it's worth over-engineering. Define a TrueClass and a FalseClass, each inheriting from BooleanValue, and then use double-dispatch on that to call different member functions of a BooleanObserver interface (one for the true case, and one for the false case). `BooleanValue::construct(condition).dispatch(myobserver);`. dispatch is implemented to virtually call `myobserver.trueCase()` in TrueClass and `myobserver.falseCase()` in FalseClass. Much cleaner and more maintainable than an if statement ;-)
Steve Jessop
A: 

You can use Switch in stead which makes the more readable, but I don't if it is any faster. If you have something like :

if (condition1) {
   // do something
} else if (condition2) {
   // do something
} else if (condition3) { 
   // do something
} else if (condition4) { 
   // do something
}

I am not what can be done to speed it up. if condition4 is occurs more frequently, you might move it to the top.

fastcodejava
+5  A: 

Premature optimization is a bad idea. Use if statements where they make sense. When you discover a part of your code where its performance needs improvement, then possibly work on removing if statements from that part of your code.

If statements can be expensive because they force the compiler to generate branch instructions. If you can figure out a way to code the same logic in such a way that the compiler does not have to branch at all the code will likely be a lot faster, even if there are more total instructions. I remember being incredibly surprised at how recoding a short snippet of code to use various bit manipulations rather than doing any branching sped it up by a factor of 10-20%.

But that is not a reason to avoid them in general. It's just something to keep in mind when you're trying to wring the last bit of speed out of a section of code you know is performance critical because you've already run a profiler and various other tools to prove it to yourself.

Another reason if statements can be expensive is because they can increase the complexity of your program which makes it harder to read and maintain. Keep the complexity of your individual functions low. Don't use too many statements that create different control paths through your function.

Omnifarious
+1 for mentioning that premature optimization is a bad idea
chrmue
+1  A: 

An if-statement implies a conditional branch which might be a bit more expensive that a code that doesn't branch.

As an example, counting how many times a condition is true (e.g how many numbers in a vector are greater than 10000):

for (std::vector<int>::const_iterator it = v.begin(), end = v.end(); it != end; ++it) {
    //if (*it > 10000) ++count; 
    count += *it > 10000;
}

The version which simply adds 1 or 0 to the running total may be a tiny amount faster (I tried with 100 million numbers before I could discern a difference).

However, with MinGW 3.4.5, using a dedicated standard algorithm turns out to be noticeably faster:

count = std::count_if(v.begin(), v.end(), std::bind2nd(std::greater<int>(), 10000));

So the lesson is that before starting to optimize prematurely, using some tricks you've learnt off the internets, you might try out recommended practices for the language. (And naturally make sure first, that that part of the program is unreasonably slow in the first place.)

Another place where you can often avoid evaluating complicated conditions is using look-up tables (a rule of thumb: algorithms can often be made faster if you let them use more memory). For example, counting vowels (aeiou) in a word-list, where you can avoid branching and evaluating multiple conditions:

unsigned char letters[256] = {0};
letters['a'] = letters['e'] = letters['i'] = letters['o'] = letters['u'] = 1; 

for (std::vector<std::string>::const_iterator it = words.begin(), end = words.end(); it != end; ++it) {
    for (std::string::const_iterator w_it = it->begin(), w_end = it->end(); w_it != w_end; ++w_it) {
        unsigned char c = *w_it;
        /*if (c == 'e' || c == 'a' || c == 'i' || c == 'o' || c == 'u') {
            ++count;
        }*/
        count += letters[c];
    }
} 
visitor
A: 

In a data structures course, the performance of an if statement doesn't matter. The small difference between an if statement and any of the obscure alternatives is totally swamped by the difference between data structures. For instance, in the following pseudocode

FOR EACH i IN container
  IF i < 100
    i = 100
  container.NEXT(i)
END FOR

the performance is most determined by container.NEXT(i); this is far more expensive for linked lists then it is for contiguous arrays. For linked lists this takes an extra memory access, which depending on the cache(s) may take somewhere between 2.5 ns and 250 ns. The cost of the if statement would be measured in fractions of a nanosecond.

MSalters