Claudiu
Claudiu

Reputation: 229561

In C, which is faster: if with returns, or else if with returns?

Is it better to have if / else if, if every block in the if statement returns, or is it better to have a chain of ifs? To be specific, which if fastest:

A:

if (condition1) {
  code1;
  return a;
}
if (condition2) {
  code2;
  return b;
}
//etc...

B:

if (condition1) {
  code1;
  return a;
}
else if (condition2) {
  code2;
  return b;
}
//etc...

Upvotes: 1

Views: 1873

Answers (7)

paxdiablo
paxdiablo

Reputation: 882586

The C standard does not dictate what machine language gets created based on the C code. You can sometimes make assumptions if you understand the underlying architecture but even that is unwise.

The days are long past where CPUs are simple beasts now that they have pipelining, multiple levels of caches and all sorts of other wondrous things to push their speed to the limit.

You should not be worrying about this level of optimization until you have a specific problem (some would say "at all").

Write your code to be readable.

That should be rule number 1, 2 and 3. Which do you think is the greatest problem in software development, code running at 99.5% of it's maximum speed or developers spending days trying to figure out and/or fix what a colleague (or even themselves) did six months ago?

My advice is to worry about performance only when you find it's a problem, then benchmark on the target platforms to see where the greatest improvement can be gained. A 1% improvement in a if statement is likely to be dwarfed by choosing a better algorithm elsewhere in your code (other things, such as number of times the code is called, being equal of course). Optimization should always be targeted to get the best bang-per-buck.

Upvotes: 14

Jeremy Cron
Jeremy Cron

Reputation: 2392

Write a simple test program to measure this and find out - but yes this is needless optimization.

Upvotes: 1

Anzurio
Anzurio

Reputation: 17014

I don't really think it is a big difference if any:

For the A case:

if (condition){
    //conditionOp
    //cmp ... , ...
    //jxx :toEndIf
    code;
    return bar;
    //mov eax, bar
    //jmp :toEnd
}
if(condition){
    //conditionOp
    //cmp ... , ...
    //jxx :toEndIf
    code;
    return bar;
    //mov eax, bar
    //jmp :toEnd
}

For the B case:

if(condition){
    //conditionOp
    //cmp ... , ...
    //jxx :toElse + 1
    code;
    return bar;
    //mov eax , bar
    //jmp :toEnd
} else 
    //jmp :endElse 
if (condition2){
    //conditionOp
    //cmp ... , ...
    //jxx :endElse
    code;
    return bar;
    //mov eax, bar
    //jmp :toEnd
}

Thus, using the B case, one extra instruction is added. Though, optimizing for size may get rid of that.

Upvotes: 2

Mike Daniels
Mike Daniels

Reputation: 8642

It makes no difference, and this is a needless attempt at micro-optimization.

Upvotes: 44

Unknown
Unknown

Reputation: 46821

They should be equivalent on most architectures. The instructions generated are probably still the same bne, cmps and rets.

What might help is if you use a switch/case instead of if statement.

Upvotes: 2

smcameron
smcameron

Reputation: 2557

With those returns, the else is superflous. The compiler is likely smart enough to figure this out.

I suspect the compiler will generate the same code for both. Disassemble it and see.

In any case, examining the output of the compiler and empirical performance testing is the only way to be sure.

Upvotes: 3

Foredecker
Foredecker

Reputation: 7491

This should perform the same in the optimized builds. If not, then something else is likely preventing the compiler from doing the "right thing".

Robbotic is incorrect. In both instances, if the first clause is true, then the subsiquent statements will not be executed (evaluated).

Note, be sure to measure - you may be optimizing the wrong thing.

Upvotes: 0

Related Questions