在这个代码中:
if (value >= x && value <= y) {
当 value >= x
和 value <= y
像真和假一样没有特定的模式时,使用 ABC2操作符会比使用 &&
快?
具体来说,我在考虑 &&
如何懒惰地计算右侧表达式(即只有在 LHS 为真的情况下) ,这意味着一个条件,而在 Java &
中,在这个上下文中保证严格计算两个(布尔)子表达式。这两种方法的值结果是相同的。
但是,虽然 >=
或 <=
操作员将使用一个简单的比较指令,&&
必须涉及一个分支,和 该分支容易出现分支预测失败-根据这个非常著名的问题: 为什么处理排序的数组比处理未排序的数组更快?
因此,强制表达式没有惰性组件肯定会更具确定性,而且不容易出现预测失败。对吧?
备注:
if(value >= x && verySlowFunction())
。我专注于“足够简单”的 RHS 表达式。if
语句)。我不能完全向自己证明这是不相关的,替代配方可能是更好的例子,如 boolean b = value >= x && value <= y;
更新 解释一下我为什么感兴趣: 我一直在关注马丁 · 汤普森在他的 机械同情博客上写的系统,在他来之后,关于 Aeron 的 谈了谈。其中一个关键信息是我们的硬件拥有所有这些神奇的东西,而我们软件开发人员悲剧性地未能利用它。别担心,我不会对我所有的代码都使用 s/& &/&/: ... ... 但是在这个网站上有很多关于通过删除分支来改进分支预测的问题,而且我突然想到,条件布尔运算符是测试条件的 在核心。
当然,@StephenC 提出了一个奇妙的观点,即将代码弯曲成奇怪的形状可以使 JIT 不那么容易发现常见的优化——如果不是现在,那么将来也是如此。上面提到的非常著名的问题是特殊的,因为它使预测的复杂性远远超出了实际的优化。
我非常清楚,在大多数情况下(或 几乎全部) ,&&
是最清晰,最简单,最快,最好的事情做-虽然我非常感谢的人谁张贴的答案证明了这一点!我真的很感兴趣,看看在任何人的经验中是否真的存在这样的情况: “ &
能更快吗?”可能是 是的。
更新2 : (针对问题过于宽泛的建议。我不想对这个问题做重大修改,因为它可能会损害下面的一些答案,这些答案的质量非常好!)也许我们需要一个野外的例子,它来自于 番石榴朗马斯类(非常感谢@maaartinus 找到它) :
public static boolean isPowerOfTwo(long x) {
return x > 0 & (x & (x - 1)) == 0;
}
看到第一个 &
了吗?如果你检查链接,下一个方法被称为 lessThanBranchFree(...)
,这暗示我们在避免分支的领域-和番石榴真正被广泛使用: 每节省周期导致海平面明显下降。那么让我们这样来回答这个问题: 这种使用 ABC0(其中 &&
将是更正常的)是一个真正的优化?