tags:

views:

409

answers:

11

I've seen statements like this

if(SomeBoolReturningFunc())
{
    //do some stuff
    //do some more stuff
}

and am wondering if putting a function in an if statement is efficient, or if there are cases when it would be better to leave them separate, like this

bool AwesomeResult = SomeBoolReturningFunc();
if(AwesomeResult)
{
    //do some other, more important stuff
}

...?

+22  A: 

I'm not sure what makes you think that assigning the result of the expression to a variable first would be more efficient than evaluating the expression itself, but it's never going to matter, so choose the option that enhances the readability of your code. If you really want to know, look at the output of your compiler and see if there is any difference. On the vast majority of systems out there this will likely result in identical machine code.

Ed Swangren
+1. the compiler will optimize both of those to be exactly the same. Even a non-optimizing compiler might not generate different machine code for these, since it would likely keep the boolean in a register the whole time anyways.
rmeador
+4  A: 

either way it should not matter. the basic idea is that the result will be stored in a temporary variable no matter what, whether you name it or not. Readability is more important nowadays because computers are normally so fast that small tweaks don't matter as much.

Scott M.
+2  A: 

I've certainly seen if (f()) {blah;} produce more efficient code than bool r = f(); if (r) {blah;}, but that was many years ago on a 68000.

These days, I'd definitely pick the code that's simpler to debug. Your inefficiencies are far more likely to be your algorithm vs. the code your compiler generates.

Steven Fisher
A: 

Putting aside any debugging ease or readability problems, and as long as the function's returned value is not used again in the if-block; it seems to me that assigning the returned value to a variable only causes an extra use of the = operator and an extra bool variable stored in the stack space - I might speculate further that an extra variable in the stack space will cause latency in further stack accesses (not sure though).

The thing is, these are really minor problems and as long as the compiler has an optimization flag on, should cause no inefficiency. A different case I'd consider would be an embedded system - then again, how much damage could a single, 8-bit variable cause? (I have absolutely no knowledge concerning embedded systems, so maybe someone else could elaborate on this?)

Dunya Degirmenci
+1  A: 

as others have said, basically makes no real difference in performance, generally in C++ most performance gains at a pure code level (as opposed to algorithm) are made in loop unrolling.

also, avoiding branching altogether can give way more performance if the condition is in a loop.

for instance by having separate loops for each conditional case or by having a statements that inherently take into account the condition (perhaps by multiplying a term by 0 if its not wanted)

and then you can get more by unrolling that loop

templating your code can help a lot with this in a "semi" clean way.

Keith Nicholas
A: 

If you put the statements on different lines, you can change the return value in the debugger to force the codepath for unit test (esp. if it is an error path).

A disadvantage for multiple lines is that you have to know the type of the return for the variable declaration. If the return is changed from bool to int then depending on the types involved you could have a truncated value in the local variable (which could make the if malfunction).

Somebody said they saw a difference in generated code. I sincerely doubt that with an optimizing compiler.

Peeter Joot
A: 

The AwesomeResult version can be faster if SomeBoolReturningFunc() is fairly slow and you are able to use AwesomeResult more than once rather than calling SomeBoolReturningFunc() again.

Adisak
A: 

Placing the function inside or outside the if-statement doesn't matter. There is no performance gain or loss. This is because the compiler will automatically create a place on the stack for the return value - whether or not you've explicitly defined a variable.

Trey Sargent
+1  A: 

There is also the possibility of

if (bool AwesomeResult = SomeBoolRetuningFunc()) { ... }

:)

IMO, the kind of statements you have seen are clearer to read, and less error prone:

bool result = Foo();
if (result) {
    //some stuff
}
bool other_result = Bar();
if (result) { //should be other_result? Hopefully caught by "unused variable" warning...
    //more stuff
}
UncleBens
+1  A: 

Both variants usually produce the same machine code and run exactly the same. Very rarely there will a performance difference and even in this cases it will unlikely be a bottleneck (which translates into don't bother prior to profiling).

The significant difference is in debugging and readability. With a temporary variable it's easier to debug. Without the variable the code is shorter and perhaps more readable.

If you want both easy to debug and easier to read code you should better declare the variable as const:

const bool AwesomeResult = SomeBoolReturningFunc(); 
if(AwesomeResult) 
{ 
    //do some other, more important stuff 
}

this way it's clearer that the variable is never assigned to again and there's no other logic behind its declaration.

sharptooth
A: 

In the performance tuning I've done, this would only be thought about in the final stage of cycle-shaving after cleaning out a series of significant performance issues.

Mike Dunlavey