【问题标题】:Why put the most likely condition first in an `if-else` statement?为什么将最可能的条件放在“if-else”语句中?
【发布时间】:2014-11-27 21:58:50
【问题描述】:

我经常听到这个问题,以至于实际上质疑它 - 许多人说,在 if-else 语句中,应该将最有可能为真的条件放在首位。所以,如果condition大部分时间可能为假,则将!condition放在if语句中,否则使用condition。一些人为的说明我的意思:

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

if (!unlikely) {
    // do this
} else {
    // do that
}

有人说这样效率更高——可能是由于分支预测或其他优化,我从来没有真正询问过该主题何时被破坏——但据我所知,总会有一个测试,并且两条路径都会导致跳转。

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

【问题讨论】:

  • 我以前没有听过这个特别的建议。我怀疑这只是个人喜好。
  • 从来没有这样听过。应该没关系,
  • 我个人不喜欢 if (!...) else,因为我总是需要一个额外的时钟周期才能弄清楚如何到达 else 块。
  • @templatetypedef 对于现代 CPU 上的单个 if/else 不应该也没有理由这样做 - 将是个人偏好,但对于嵌套 if/else_if/else_if/else 手动排序可能会有显着收益分支取决于数据。

标签: if-statement language-agnostic


【解决方案1】:

顺序可能很重要的原因有两个:

  1. 由于已知数据分布,多个 if/else_if/else_if/else 语句的多个分支具有不同的概率

样品 - 分类苹果,大多数是好的黄色一次 (90%),但有些是橙色 (5%),有些是其他颜色 (5%)。

 if (apple.isYellow) {...}
 else if (apple.isOrange) {....}
 else {...}   

对比

 if (!apple.isYellow && !apple.isOrange) {...}   
 else if (apple.isOrange ) {....}
 else  {...}

在第一个样本中,90% 的苹果只选中了一个 if 检查,而 10% 的苹果会命中 2,但在第二个样本中,只有 5% 的苹果命中了一个检查,而 95% 的苹果命中了两个。

因此,如果您知道使用一个分支的机会之间存在显着差异,那么将其提升为第一个条件可能会很有用。

请注意,您的单一 if 样本在该级别上没有任何区别。

  1. 可能有利于其中一个分支的低级 CPU 优化(这更多是关于传入数据始终达到相同条件分支)。

与顺序执行代码的情况相比,如果执行条件跳转,较早/更简单的 CPU 可能需要清除命令解析管道。所以这可能是提出这种建议的原因。

样品(假组装):

    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: 
    ....

现代 CPU 不应该有这个问题,因为它们会解析两个分支的命令。他们甚至有条件的分支预测逻辑。因此,如果条件主要以一种方式解决,CPU 将假定条件将以特定方式解决并开始在该分支中执行代码检查完成之前。据我所知,在当前的 CPU 上,它是条件的第一个分支还是替代分支都无关紧要。查看Why is it faster to process a sorted array than an unsorted array? 了解相关信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-09
    • 2019-03-05
    • 2016-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多