我有一个简短的问题。
我有一个循环,看起来像这样:
for (int i = 0; i < dim * dim; i++)
for循环中的条件在每次循环中都会重新评估吗?
如果是这样,像下面这样做是否更有效?:
int dimSquare = dim * dim;
for (int i = 0; i < dimSquare; i++)
谢谢
-Faken
我有一个简短的问题。
我有一个循环,看起来像这样:
for (int i = 0; i < dim * dim; i++)
for循环中的条件在每次循环中都会重新评估吗?
如果是这样,像下面这样做是否更有效?:
int dimSquare = dim * dim;
for (int i = 0; i < dimSquare; i++)
谢谢
-Faken
是的,语义上它将在每次循环中被评估。在某些情况下,编译器可能会自动从循环中删除条件,但并非总是如此。特别是:
void foo(const struct rect *r) {
for (int i = 0; i < r->width * r->height; i++) {
quux();
}
}
编译器不能在这种情况下移动乘法操作,因为对于它而言,quux()
函数修改了 r
的值,所以局部变量通常才能被提取出循环表达式(假设你不会取地址)。虽然在某些条件下结构体成员也可能被提取,但许多情况下编译器会认为内存中的内容已经发生改变,比如写入任何指针或调用几乎任何函数。因此,如果你在循环中使用了任何非局部变量,最好假设优化不会发生。一般来说,如果您在循环内更改“dim”的值,它将每次重新评估。但由于在您的示例中不是这种情况,一个好的编译器会优化您的代码,您不会看到性能上的任何差异。
编译器将在循环开始之前预先计算Dim * Dim的值。
const struct rect *
,但编译器仍然不允许假定quux()不会通过别名修改其数据成员。通常认为const会激活各种编译器优化,但实际上并不像人们最初想象的那么简单。 - Steve Jessopquux()
不可能修改r
,除非r
是一个全局变量。我有什么遗漏吗? - GManNickG