我有一个看起来像这样的循环:
for (int i = 0; i < dim * dim; i++)
for 循环中的条件是否在每个循环中重新计算?
如果是这样,这样做会更有效率吗?:
int dimSquare = dim * dim;
for (int i = 0; i < dimSquare; i++)
是的,从语义上讲,它将在每个循环上进行评估。在“某些情况下”,编译器“可能”能够自动从循环中删除条件 - 但并非总是如此。特别是:
void foo(const struct rect *r) {
for (int i = 0; i < r->width * r->height; i++) {
quux();
}
}
在这种情况下,编译器将无法将乘法移出,就其所知
quux()
修改
r
。
一般来说,通常只有局部变量才有资格将表达式提升出循环(假设您从未获取它们的地址!)。虽然在某些情况下结构成员也可能符合条件,但有很多事情可能会导致编译器假设内存中的所有内容都已更改 - 例如,写入几乎任何指针,或调用几乎任何函数。因此,如果您在那里使用任何非本地变量,最好假设优化不会发生。
也就是说,一般来说,我只建议主动将可能昂贵的代码移出该条件,如果:
这样做不会损害可读性
显然会花费
编译器会在循环开始前预先计算 Dim * Dim 的值