每次迭代都会重新评估循环的条件吗? [重复]

问题描述 投票:0回答:3

我有一个看起来像这样的循环:

for (int i = 0; i < dim * dim; i++)

for 循环中的条件是否在每个循环中重新计算?

如果是这样,这样做会更有效率吗?:

int dimSquare = dim * dim;
for (int i = 0; i < dimSquare; i++)
c++ for-loop optimization compiler-optimization loop-invariant
3个回答
51
投票

是的,从语义上讲,它将在每个循环上进行评估。在“某些情况下”,编译器“可能”能够自动从循环中删除条件 - 但并非总是如此。特别是: void foo(const struct rect *r) { for (int i = 0; i < r->width * r->height; i++) { quux(); } } 在这种情况下,编译器将无法将乘法移出,就其所知

quux()
 修改 
r


一般来说,通常只有局部变量才有资格将表达式提升出循环(假设您从未获取它们的地址!)。虽然在某些情况下结构成员也可能符合条件,但有很多事情可能会导致编译器假设内存中的所有内容都已更改 - 例如,写入几乎任何指针,或调用几乎任何函数。因此,如果您在那里使用任何非本地变量,最好假设优化不会发生。

也就是说,一般来说,我只建议主动将可能昂贵的代码移出该条件,如果:

这样做不会损害可读性

显然会花费
    非常
  • 很长的时间(例如网络访问)
  • 或在分析中显示为热点。
  • 一般来说,如果您要更改循环内“dim”的值,则每次都会重新评估它。但由于您的示例中并非如此,因此一个不错的编译器会优化您的代码,并且您不会看到性能有任何差异。

38
投票

编译器会在循环开始前预先计算 Dim * Dim 的值


-4
投票

© www.soinside.com 2019 - 2024. All rights reserved.