"if, if, if"或"if, else if, else if, else"
To "if, if, if" or to "if, else if, else if, else"
我正在编写一些用于数据分析的代码,并且必须根据某些标准排除样本。在实践中,我最终编写了这样的代码:
bool Test(SampleType sample)
{
if( ! SubTest1(sample) )
return false;
if( ! SubTest2(sample) )
return false;
if( ! SubTest3(sample) )
return false;
return true;
}
对我来说,以下内容似乎是等价的:
bool Test(SampleType sample)
{
if( ! SubTest1(sample) )
return false;
else if( ! SubTest2(sample) )
return false;
else if( ! SubTest3(sample) )
return false;
else
return true;
}
在计算成本方面有差异吗?在可扩展性/可维护性、美观性等方面是否存在可争议的优先选择?
我知道这可能是一个无关紧要的问题,但是一旦这些问题在我的脑海里挥之不去,我就需要找到答案。
PS:如果有人关心,我的实际代码作为15/09可以在下面找到:http://folk.uio.no/henrikq/conf.tgz
编译器为两个版本生成相同的代码。但是第一个版本在可维护性方面比第二个版本要好。
遇到return
语句时退出;因此,在即将到来的if
中保留else
是没有用的。它使开发人员更好地理解代码。
同样,如果这是文字代码,那么你仍然可以收缩为
bool Test(SampleType sample)
{
return (SubTest1(sample) && SubTest2(sample) && SubTest3(sample));
}
我会这样做:
return SubTest1(sample) && SubTest2(sample) && SubTest3(sample);
这不会提高性能,但函数的功能可能(也可能不)更明显。
两者在行为上是完全等同的,编译器可能会为两者发出相同的机器码。
它们在可读性方面甚至没有太大的区别——它们都有相同数量的嵌套。
在可读性方面,
bool Test( SampleType sample )
{
return SubTest1( sample )
&& SubTest2( sample )
&& SubTest3( sample );
}
比你的任何一个选项都清晰得多。否则,你肯定希望else
明确表示,一旦有一个条件只要满足了,其他的都不需要测试。
两者完全相同。编译器可能会找出如何优化它们,以便发出相同的机器码。我将选择第一个代码,因为它更容易阅读。
我想象不出这对性能有什么影响。
如果它们是独立的测试,我将使用第一个,并且您只想在其中一个成功后退出,如果它在一组逻辑替代方案之间进行选择,我将使用第二个。
据我所知,生成的机器代码没有区别。除此之外,谁在乎呢?这段代码有性能问题吗?性能是一个困难的主题,通常应该留在项目结束时,只有当有性能问题,他们应该被发现和修复,他们实际上存在,而不是在你认为他们可能提前。
这主要取决于编译器如何优化生成的代码。
if(.)通常用compare_to_zero指令翻译,后面跟着条件跳转。
在你的例子中,这将是
CMP(c1)
RETZ
CMP(c2)
RETZ
CMP(c3)
RETZ
或(带else-s)
CMP(c1)
JNZ(a1)
RET
a1:CMP(c2)
JNZ(a2)
RET
a2:CMP(c3)
JNZ(a3)
RET
a3:RET
优化器的第二次传递将看到跳转链,反转then/else(和Z/NZ)跳过跳转,处于"跳转到下一个"点,给出之前的代码。
这取决于语言和周围的api
第一个解决方案是典型的命令式方法,重点是检查某些事情的行为:如果a中止,如果b中止,如果c中止,成功。
第二种解决方案是一种更实用的方法,可以将其读作数学定义中的花括号(如:fac(n) = { n <= 1: 1, n > 1: n * fac(n-1)
)。
应选择与环境相匹配的解决方案。在Java、Python等中,它将是第一个。在ruby中,第二个就可以了。
有一个好的做法叫做"一个入口,一个出口"。这意味着在一个函数中最好只有一个返回。
现在,你的函数是简单的,但在将来,它可能会增长,变得更复杂,分配临时变量必须被释放,等等。
所以最好在任何地方都使用好的实践。它被称为"防御性编程",防御人类的失败(我和我的同事)。
我会这样写:
bool Test(SampleType sample)
{
bool bRet = true; // by default, set it to the most "defensive" value which will cause the less harm or make the problem evident
// in the future, you may have inits and allocations here
if ( !SubTest1(sample) )
bRet = false; // don't match
else if ( !SubTest2(sample) )
bRet = false; // don't match
else if ( !SubTest3(sample) )
bRet = false; // don't match
else
; // bRet stays true
// thanks to the single point of exit, you can do things like that
if (bRet)
log("... match");
else
log("...no match")
// here you clean temporary resources...
return bRet;
}
如果您想提高性能,最好的方法是将SubTestX函数按最佳顺序排列,以便最不匹配的函数排在前面,因此需要较少的测试来发现它不匹配。
- 我的简单if-else语句是如何无法访问的代码
- 如何删除peer if else分支中的冗长句子
- 我似乎对if/else的基本语句有问题:/
- 使用if-else将数字转换为单词
- 为什么这个案例陈述需要一个"if else"而不仅仅是一个"if"?
- C++ If/Else 语句被跳过
- 如果条件不相关,我应该更喜欢两个 if 语句而不是 if-else 语句吗?
- 如何将 if else 语句重写为 switch 语句
- 在 C++ 中的 if-else if- else 语句期间更改变量
- 为什么我的 if else 语句不起作用并从数组中输出正确的索引?
- 我的 If Else 语句无法在向量 (C++) 中提供最大值
- 具有嵌套 if-else 的循环的时间复杂度
- 为什么无论输入如何,所有 if-else 语句都会打印?
- 简化对两个布尔值的 4 个 if/else 检查
- 如何在C++中创建 if else 循环而不是多个嵌套?
- 为什么切换 if else 语句的顺序会导致错误?
- 如何使用 if else 语句
- if/else 语句输出由于加号或减号而未显示正确的消息
- 如何解释 #if/#else 位域?(VC++菜鸟)
- if-else 语句仅按特定顺序工作,我不知道为什么