I have code like this, and I find it a bit hard to read:
// code1
if( (expensiveOperation1() && otherOperation() && foo())
|| (expensiveOperation2() && bar() && baz()) {
// do something
}
I just changed it to the following, to make it more readable:
// code2
const bool expr1 = expensiveOperation1() && otherOperation() && foo();
const bool expr2 = expensiveOperation2() && bar() && baz();
if(expr1 || expr2){
// one of the conditions met
}
But should I now be concerned about efficiency?
I mean, in code1
, if the first conjunctive clause is fulfilled then it won't even bother to look at the second one because it's already clear that the statement will be true.
But in my more readable example, both cond1
and cond2
have to be computed. Or will the compiler be smart enough to change my code2
into code1
if expr2 is not used anywhere else?
I would say it shouldn't, since they're not logically equivalent if any of the functions have side-effects.
The following would be equivalent however, and it'd have the advantage allowing you to give descriptive names to the test functions, making the code more self-documenting:
// code3
inline bool combinedOp1()
{
return expensiveOperation1() && otherOperation() && foo();
}
inline bool combinedOp2()
{
return expensiveOperation2() && bar() && baz();
}
And then call it as follows:
if (combinedOp1() || combinedOp2())
{
// do something
}