至“if,if,if”或“if,else if else 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的实际代码可以在以下url找到: 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); 

这不会提高性能,但function可能会(或可能不会)更明显。

两者在行为方面完全相同,编译器可能会为两者发出相同的机器代码。

它们在可读性方面甚至没有那么大差别 – 两者都具有相同的嵌套量。 将此与没有早期返回导致深度嵌套的情况相比较。

在可读性方面,

 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则中止,成功。

第二种解决方案是一种function更强大的方法,可以将其视为数学定义中的大括号(如: fac(n) = { n <= 1: 1, n > 1: n * fac(n-1) ) 。

应选择解决方案以匹配环境。 在Java,Python等中,它将是第一个。 在ruby中,第二个可能没问题。

有一种很好的做法叫做“一个入境点,一个出口点”。 这意味着在一个函数中只有一个返回更好。

目前,您的function很简单,但将来它可能会增长,变得更加复杂,分配必须释放的临时变量等。

因此,最好在各地使用好的做法。 它被称为“防御性编程”,防御人类失败(我和同事们)。

我会这样写:

 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函数放在最佳顺序,以便最常匹配的那个是第一个,因此需要较少的测试来查找它不匹配。