Reputation: 6240
I've a conditional statement expensive_foo()
which is false in 99.9% cases. And I have a conditional statement bar
which is true in ~50% cases.
And I want some action be done if both statements are true. So I almost certainly know that expensive_foo()
is false and I want to check it only if bar
is true.
Will the code below check the expensive_foo()
ONLY if bar
is true? Or it will check expensive_foo()
every time?
if ( bar && expensive_foo() )
{
...
}
Or I need to make a structure like this:
if ( bar )
{
if ( expensive_foo() )
{
...
}
}
Upvotes: 3
Views: 1833
Reputation: 21965
I saw a comment that the compiler can re-order operations and I'm inclined to that opinion. The efforts to improve automatic parallelization of the sequential programs has resulted in somewhat better compilers and it helps a programmer to avoid complex routines of parallelization from their programs. The compiler could re-order the operations provided the re-ordering does not violate/worsen the locality or in a broad sense doesn't violate the actual intention of the of the program.
But I doubt the fact that the compiler would try to re-order a conditional statement like :
if ( bar && expensive_foo() )
If the less expensive Boolean function is put at the beginning, it is certain that we can save some time.
Upvotes: 1
Reputation: 5469
I'd be surprised if the optimized assembly for both wasn't exactly the same. expensive_foo() will never be called if bar is false.
Upvotes: 1
Reputation: 40709
The other answers are good, but I'm questioning the premise.
If you are querying a predicate that is false 99.9% of the time, that is analogous to doing linear search in a list of 2000 entries, where the item you are looking for could be anywhere with roughly equal probability.
In that case, typically one would try to organize the list differently so as to do a O(logN) (or better) search instead of O(N). I don't know if you can do this, but that is where I would focus.
When a question is being asked with highly skewed probability, that can be a big speedup opportunity, if one can un-skew it. (Assuming a big % of time is spent in this activity. If not, the point is moot.)
Upvotes: 1
Reputation: 477620
The logical AND operator &&
is short-circuited, which means that it is guaranteed the second operand is evaluated if and only if the first one is evaluated as true
. The conditions if (bar && foo)
and if (bar) if (foo)
are identical.
Given that foo
is expensive to compute, you should almost definitely check bar
first. Even though bar
won't be predictable by the branch predictor very well, that's a minor effect compared to the computation of foo
.
Thus the structure should probably be:
if (bar)
{
if (bool const foo = compute()) // expensive
{
// ...
}
}
Note that all of those constructions mean that we may or may not call compute()
. If you require the function call unconditionally, then you should make it the first check. In that case, the successful branch prediction on the result should be exploited.
Upvotes: 5
Reputation: 864
Both codes will check foo
only in case bar
is true. In first case this is guaranteed by the language lazy boolean expression evaluation (which actually could be explicitly turned off in some compilers, but is ON by default).
Upvotes: 2