选项1:
boolean isFirst = true;
for (CardType cardType : cardTypes) {
if (!isFirst) {
descriptionBuilder.append(" or ");
} else {
isFirst = false;
}
//other code not relevant to this theoretical question
}
选项2:
boolean isFirst = true;
for (CardType cardType : cardTypes) {
if (!isFirst) {
descriptionBuilder.append(" or ");
}
isFirst = false;
//other code not relevant to this theoretical question
}
我的分析: 两种代码具有相同的语义。
第一段代码) 我不确定这段代码是否有两个分支(从分支预测的角度来看),还是只有一个分支。我查阅了http://en.wikipedia.org/wiki/X86_instruction_listings,但无法找到类似“如果先前条件值为false,则跳转到此处”的X86指令,以避免两次分支预测(非常糟糕)。
第二段代码) 很可能始终执行简单的MOV操作(移动至寄存器或元素,很可能已经在缓存中),这样比较廉价(最多几个周期)。
因此,我认为除非处理器解码为微码指令时能够做出一些聪明的事情,或者存在X86指令以避免必要的分支预测,否则第二段代码更快。
我知道这纯粹是理论问题,因为在实践中,这个分支可能使应用程序变快0.000000002%或类似的速度。
我错过了什么吗?
编辑:我添加了一个循环,以便更加重视所讨论的分支。
编辑2:这个问题涉及Intel架构的分支预测(Pentium及更高版本处理器)。
jmp
相同廉价。当然,更好的方法是编译器将asm循环中的第一次迭代提升/剥离出来,或者在非第一次迭代工作后跳入其中,因此在循环中没有实际的if分支。但是,如果编译器足够聪明以执行此操作,则可能会发生在两个测试中,因此此基准测试不会捕获它(并且与此兼容,因为273... +- 1个数字在误差范围内)。 - Peter Cordes