If statement 为什么要把最可能的条件放在“if-else”语句的前面?

If statement 为什么要把最可能的条件放在“if-else”语句的前面?,if-statement,language-agnostic,If Statement,Language Agnostic,我经常听到这句话,以至于对它提出质疑——许多人说,在if-else语句中,应该首先考虑最有可能为真的条件。因此,如果条件在大多数情况下可能是错误的,请将放入!if语句中的条件,否则使用条件。对我的意思的一些人为的说明: if (likely) { // do this } else { // do that } if (!unlikely) { // do this } else { // do that } 有人说这更有效——可能是因为分支预测或其他优化,我

我经常听到这句话,以至于对它提出质疑——许多人说,在if-else语句中,应该首先考虑最有可能为真的条件。因此,如果
条件
在大多数情况下可能是错误的,请将
放入!if语句中的条件
,否则使用条件。对我的意思的一些人为的说明:

if (likely) {
    // do this
} else {
    // do that
}

if (!unlikely) {
    // do this
} else {
    // do that
}
有人说这更有效——可能是因为分支预测或其他优化,我从来没有真正询问过主题何时被突破——但据我所知,总是会有一个测试,两条路径都会导致跳转


因此,我的问题是——是否有一个令人信服的理由(其中“令人信服的理由”可能是微小的效率提高)为什么最有可能为真的条件应该首先出现在if-else语句中?

顺序之所以重要,有两个理由:

  • 由于已知的数据分布,多个if/else\u if/else\u if/else语句的多个分支具有不同的概率
  • 样品分类的苹果,大多数是好的黄色(90%),但有些是橙色(5%),有些是其他颜色(5%)

    vs

    在第一个样本中,90%的苹果只进行了一次if检查,10%的苹果会进行2次检查,但在第二个样本中,只有5%的苹果进行了一次检查,95%的苹果进行了两次检查

    因此,如果您知道使用一个分支的机会之间存在显著差异,那么将其上移到第一个条件可能会很有用

    请注意,您的单个if示例在该级别上没有差异

  • 可能有利于其中一个分支的低级别CPU优化(这更多的是关于传入数据,以一致地命中相同的条件分支)
  • 若执行条件跳转,则早期/更简单的CPU可能需要清除命令解析管道,而不是按顺序执行代码。因此,这可能是提出这种建议的一个原因

    样品(假装配):


    现代CPU不应该有这个问题,因为它们会解析两个分支的命令。它们甚至有条件的分支预测逻辑。所以,若条件主要是单向解决的,CPU将假定条件将以该特定方式解决,并在检查完成之前开始在该分支中执行代码。据我所知,在当前CPU上,它是条件的第一个分支还是替代分支并不重要。查看这方面的好信息。

    我以前没有听过这条建议。我怀疑这只是个人喜好,从来没听说过这样的话。这两种方式都不重要,我个人不喜欢
    if(!…)else
    ,因为我总是需要额外的时钟周期来确定如何到达
    else
    块。@templatetypedef在现代CPU上使用单个if/else应该没有理由——这是个人的偏好,但是对于嵌套的if/else\u if/else\u if/else,根据数据手动排序分支可能会有很大的好处。
     if (apple.isYellow) {...}
     else if (apple.isOrange) {....}
     else {...}   
    
     if (!apple.isYellow && !apple.isOrange) {...}   
     else if (apple.isOrange ) {....}
     else  {...}
    
        IF R1 > R2 JUMP ElseBranch
        ADD R2, R3 -> R4  // CPU decodes this command WHILE executing previous IF
        ....
        JUMP EndCondition  
    ElseBranch:    
        ADD 4, R3 -> R4   // CPU will have to decodes this command AFTER
                          // and drop results of parsing  ADD R2, R3 -> R4  
        ....
    EndCondition: 
        ....