我有这样的代码,我发现它有点难以阅读:
// code1 if( (expensiveOperation1() && otherOperation() && foo()) || (expensiveOperation2() && bar() && baz()) { // do something }
我只是将其更改为以下内容,以使其更具可读性:
// code2 const bool expr1 = expensiveOperation1() && otherOperation() && foo(); const bool expr2 = expensiveOperation2() && bar() && baz(); if(expr1 || expr2){ // one of the conditions met }
但我现在应该关注效率吗?
我的意思是code1
,如果第一个联合条款得到满足,那么它甚至不会费心去看第二个,因为已经清楚该陈述是真的.
但是,在我更可读的示例中,cond1
并cond2
必须计算.或者编译器是否足够聪明,如果expr2没有在其他任何地方使用,我可以将其更改code2
为code1
?
我会说它不应该,因为如果任何功能都有副作用,它们在逻辑上是不相同的.
但是,以下内容是等效的,并且它具有允许您为测试函数提供描述性名称的优点,使代码更加自我记录:
// code3 inline bool combinedOp1() { return expensiveOperation1() && otherOperation() && foo(); } inline bool combinedOp2() { return expensiveOperation2() && bar() && baz(); }
然后将其命名如下:
if (combinedOp1() || combinedOp2()) { // do something }
也许,但为什么不让你的第二次检查合并第一次呢?
// code3 bool expr = expensiveOperation1() && otherOperation() && foo(); expr = expr || (expensiveOperation2() && bar() && baz()); if(expr){ // one of the conditions met }
更好的是,扭转局面,以便在每个列表中首先出现最便宜的检查,利用懒惰的评估来完全跳过昂贵的操作.