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

发布于 2024-07-30 07:33:15 字数 233 浏览 8 评论 0原文

我有一个如下所示的循环:

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

for 循环中的条件是否在每个循环上重新评估?

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

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

I have a loop that looks like this:

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

Is the condition in a for loop re-evaluated on every loop?

If so, would it be more efficient to do something like this?:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

骄兵必败 2024-08-06 07:33:17

一般来说,如果您要更改循环内“dim”的值,则每次都会重新评估它。 但由于您的示例中并非如此,因此一个不错的编译器会优化您的代码,并且您不会看到性能有任何差异。

In general, if you would for example change the value of "dim" inside your loop, it would be re-evaluated every time. But since that is not the case in your example, a decent compiler would optimize your code and you wouldn't see any difference in performance.

叫嚣ゝ 2024-08-06 07:33:17

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

the compiler will precompute the value of Dim * Dim before the Loop starts

围归者 2024-08-06 07:33:16

是的,从语义上讲,它将在每个循环上进行评估。 在某些情况中,编译器可能能够自动从循环中删除条件 - 但并非总是如此。 特别是:

void foo(const struct rect *r) {
  for (int i = 0; i < r->width * r->height; i++) {
    quux();
  }
}

在这种情况下,编译器将无法将乘法移出,因为它知道 quux() 会修改 r

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

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

  • 不会损害可读性 这样做
  • 显然会花费非常很长时间(例如,网络访问)
  • 或在分析中显示为热点。

Yes, semantically it will be evaluated on every loop. In some cases, compilers may be able to remove the condition from the loop automatically - but not always. In particular:

void foo(const struct rect *r) {
  for (int i = 0; i < r->width * r->height; i++) {
    quux();
  }
}

The compiler will not be able to move the multiplication out in this case, as for all it knows quux() modifies r.

In general, usually only local variables are eligible for lifting expressions out of a loop (assuming you never take their address!). While under some conditions structure members may be eligible as well, there are so many things that may cause the compiler to assume everything in memory has changed - writing to just about any pointer, or calling virtually any function, for example. So if you're using any non-locals there, it's best to assume the optimization won't occur.

That said, in general, I'd only recommend proactively moving potentially expensive code out of the condition if it either:

  • Doesn't hurt readability to do so
  • Obviously will take a very long time (eg, network accesses)
  • Or shows up as a hotspot on profiling.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文