在Java,C#或C ++中,假设我们有一个非常常见的情况,我们需要迭代很多次并执行函数doX,但是只有一次迭代我们应该执行函数doY。
int index = 123456;
for(int i = 0; i < 1000000; i++)
{
if(i == index) doY();
else doX();
}
在我看到真正的性能问题的情况下,我通常会在2中打破循环,但这可能非常痛苦,尤其是在循环体很大的情况下。编译后的代码是否真的检查每次迭代的条件,还是可以由编译器优化?此外,如果index
在编译时不是常量,那么可以进行这样的优化吗?
答案 0 :(得分:10)
这通常不会导致巨大的性能问题。这是由于branch predicting。请参阅此famous question。
分支预测基本上是汇编的方式来猜测if语句将评估的方式。如果猜对了,几乎没时间。如果它猜错了,它将回溯并导致性能问题。分支预测器通常将其先前的分支路径用作下一分支的“猜测”。
因为你的if语句几乎时间评估为false。分支预测器几乎每次都会正确预测。
所以回答你的问题“编译的代码是否真的检查每次迭代的条件?”。 不,不。虽然它没有被编译器优化,但是由汇编管道本身优化。