Reputation: 22820
Version A :
if ((A)&&(B)) doSth;
if (B) doSthElse;
Version B :
if (B)
{
if (A) doSth;
doSthElse;
}
Which of these two is preferable, performance-wise?
Notes :
The actual code will be used some millions of times per second, so performance and speed is crucial. Before proceeding to profiling, could you please give me some input in case I'm missing something?
The code is being compiled using Clang++ on Mac OS X 10.6.8, using -O3
.
Upvotes: 0
Views: 309
Reputation: 3350
If your A and B values are booleans then I'll suggest a third version:
if (A & B) doSth;
if (B) doSthElse;
This version uses bitwise AND to create a single comparison out of multiple booleans. This can also be applied to the ternary operator solution posted in another answer.
This can be beneficial because it removes a branch for every && substitution. Most of the time, AND'ing several booleans together is cheaper than doing a branch on the value of each one. This applies to any cpu architecture that has relatively expensive branching, which is anything with either out-of-order execution, or a long instruction execution pipeline (which accounts for almost everything).
Important note: On x86, the conditional executors and branch predictors are good enough that if boolean A is well-predicted (eg, rarely changes and prediction rate is above 99.6%) then its actually more efficient to use && form and shortcut past the rest of the conditional. ARM and PowerPC architectures however almost always benefit from fewer branches.
Upvotes: 0
Reputation:
Assume A and B are both simple boolean values, We need take into account the likelihood of what the condition resolves into:
short-cut evaluation: if (A) is likely to resolves to false than (B), write (A && B), otherwise (B && A).
branch predictability: use conditions that more predictable enclose big blocks. for example, if B is predictable, then 2nd form is preferred.
try to translate non-predictable conditional assignment into (? :), for example, prefer
x = c ? a : b; // data dependency
to
if (c) x = a; // control flow dependency
else x = b;
if c is not predictable. In this case, you want to substitute a control flow dependency by a data dependency, which can be compiled into a conditional move. It is net gain when the control dependency is not predictable.
Upvotes: 2
Reputation: 258638
Depends on what A
and B
are. If B
is a complicated function, the second one only evaluates it once, whereas the first one evaluates it twice (if A
holds, of course).
For trivial cases (i.e. both bool
s) it won't matter.
And, of course, you could profile, I doubt this will be a bottleneck though.
Upvotes: 3