我经常听到这个问题,实际上对它提出质疑 - 许多人说,在if-else声明中,应该首先考虑最有可能真实的条件。因此,如果condition
在大多数情况下可能都是假的,请将!condition
放在if语句中,否则使用condition
。一些人为的说明我的意思:
if (likely) {
// do this
} else {
// do that
}
if (!unlikely) {
// do this
} else {
// do that
}
有些人说这更有效率 - 可能是由于分支预测或其他一些优化,我从未真正询问过什么时候这个话题遭到破坏 - 但据我所知,总会有一个测试,并且这两条路径都会导致跳跃。
所以我的问题是 - 是否有一个令人信服的理由(“令人信服的理由”可能是一个微小的效率增益)为什么最有可能真实的条件应该首先出现在if-else语句中?
答案 0 :(得分:4)
订单可能有两个原因:
样品 - 分类苹果,大多数是黄色一次(90%),但有些是橙色(5%),有些是其他颜色(5%)。
if (apple.isYellow) {...}
else if (apple.isOrange) {....}
else {...}
VS
if (!apple.isYellow && !apple.isOrange) {...}
else if (apple.isOrange ) {....}
else {...}
在第一个样本中,90%的苹果只检查了一个苹果,10%检查了2个,但在第二个样本中,只有5%检查了一个支票,95%命中了两个。
因此,如果您知道在使用一个分支的机会之间存在显着差异,那么将其移动到第一个条件可能是有用的。
请注意,您的单个if样本在该级别上没有任何区别。
与顺序执行代码的情况相比,如果执行条件跳转,早期/更简单的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?了解相关信息。