处理循环特殊情况

Handling for loop special cases

在Java、C# 或 C++ 中,假设我们有一种非常常见的情况,我们需要迭代很多次并执行一个函数 doX,但只有一次迭代我们应该执行一个函数 doY.

int index = 123456;
for(int i = 0; i < 1000000; i++)
{
    if(i == index) doY();
    else doX();
}

在我看到真正的性能问题的情况下,我通常会在 2 中中断循环,但这可能会非常痛苦,尤其是在循环体很大的情况下。编译后的代码真的会在每次迭代时检查条件,还是可以由编译器优化?另外,如果index在编译时不是常量,能不能有这样的优化?

这通常不会导致严重的性能问题。这是由于 branch predicting. Refer to this famous question.

分支预测基本上是汇编猜测 if 语句将以哪种方式求值的方式。如果它猜对了,几乎不需要时间。如果它猜错了,它会回溯并导致性能问题。分支预测器通常会使用它之前的分支路线作为下一个分支的 "guess"。

因为您的 if 语句几乎有一段时间计算为 false。分支预测器几乎每次都会正确预测。

所以回答你的问题"Does the compiled code really check for the condition on every iteration?"。 不,它没有。虽然它不是由编译器优化的,而是由汇编管道本身优化的。