我应该将临时变量声明带出 C 和 C++ 中的循环吗?

发布于 2024-09-11 18:11:56 字数 375 浏览 13 评论 0原文

这就是我的意思,假设我有这样的代码:

for (int i = 0; i < 1000; i++) {
    char* ptr = something;
    /*
    ... use ptr here
    */
}

似乎每次在循环中都会分配 char* ptr ,从而使其无效?

这样写是不是更有效呢?

char* ptr = something;
for (int i = 0; i < 1000; i++) {
    /*
    ... use ptr here
    */
}

请评论这个有趣的问题。谢谢你!

谢谢,博达·西多。

Here is what I mean, suppose I have code like:

for (int i = 0; i < 1000; i++) {
    char* ptr = something;
    /*
    ... use ptr here
    */
}

It seems that char* ptr gets allocated every time in the loop, making it ineffective?

Is it more effective to write this?

char* ptr = something;
for (int i = 0; i < 1000; i++) {
    /*
    ... use ptr here
    */
}

Please comment on this interesting problem. Thank you!

Thanks, Boda Cydo.

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

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

发布评论

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

评论(6

对岸观火 2024-09-18 18:11:56

它可以产生性能差异,但许多优化编译器会在适当的情况下为您进行这种优化。这称为“循环不变代码运动”。

It can make a performance difference, but many optimizing compilers undertake this optimization for you, if appropriate. This is called "loop-invariant code motion".

丶视觉 2024-09-18 18:11:56

我认为最好尽可能限制变量名称的范围;如果 ptr 不打算在循环外部引用,则不应在循环外部声明它。

但是,如果某物结果是一个昂贵的操作AND,它是不变的(即,它不依赖于iAND 它阻止您的代码满足硬性能要求,那么是的,您应该将声明移到循环之外。

这是难以形容的丑陋,但你可以这样做:

do
{
  char *ptr = something;
  for (int i = 0; i < 1000; i++)
  {
    /* use ptr here */
  }
} while (0);

你仍然限制 ptr 的范围,但你不再在每次循环迭代时分配它。

I'm of the school that thinks it's better to limit the scope of variable names as much as possible; if ptr isn't meant to be referenced outside of the loop, then it should not be declared outside of the loop.

However, if something turns out to be an expensive operation AND it's invariant (i.e., it doesn't depend on i) AND it's preventing your code from meeting a hard performance requirement, then yes, you should move the declaration outside of the loop.

This is unspeakably ugly, but you can do something like this:

do
{
  char *ptr = something;
  for (int i = 0; i < 1000; i++)
  {
    /* use ptr here */
  }
} while (0);

You're still limiting the scope of ptr, but you're no longer assigning it on every loop iteration.

奈何桥上唱咆哮 2024-09-18 18:11:56

代码的翻译方式实际上取决于您的编译器及其执行的优化。编译器可能会执行“哑”转换并分配每个循环,或者可能会在优化阶段将分配放置在循环之外。为了安全起见,我会将声明放在循环之外。与任何事情一样,您可以测试两者并查看每个循环需要多长时间才能查看是否存在差异。

The way that code gets translated really depends on your compiler and the optimizations it performs. The compiler might perform a "dumb" translation and allocate every loop, or it might place the allocation outside the loop for you in it's optimization phase. To be safe, I would place the declaration outside the loop. As with anything, you could test out both and see how long each loop takes to see if there is a difference.

智商已欠费 2024-09-18 18:11:56

您必须亲自分析并查看。 查看我的这个问题(以及已接受的答案)作为参考。正如 jalf 所说,这只是一个经验法则它会被优化掉(对于 POD 类型来说它可能是正确的)但是您需要通过分析来支持它。

You have to profile and see for yourself. Check out this question (and the accepted answer) of mine as a reference. As jalf says, it's just a rule of thumb to expect it to be optimized away (and it's probably correct for POD types) but you'll need to back it up with profiling.

稀香 2024-09-18 18:11:56

作为“C”程序中的个人惯例,我喜欢将变量声明放在函数顶部、文件顶部或公共 .h 文件中。如果我开始在代码中隐藏声明,则可能会造成混乱,并且很容易失去对变量范围的跟踪,从而导致不必要的后果。

As a matter of personal convention in 'C' programs, I like to put variable declarations at the top of the function, top of the file or in a common .h file. If I start to bury declarations within the code it could potentially be confusing and easy to lose track of variable scope, resulting in unwanted consequences.

清泪尽 2024-09-18 18:11:56

对于示例中的 char* 等内置类型,没有太大区别。第二种形式在循环退出后可用,并且仅对初始值设定项求值一次。但正如约翰所说,大多数编译器无论如何都会预先计算初始化。

如果 ptr 在循环内重新分配(如果不重新分配它,则应该将其设置为 char* const ptr),则存在明显的区别,因为值将保留上一次迭代的值,而不是重置。

最后,非 POD 类型的构造函数和析构函数将在每次循环迭代时运行。

For built-in types such as the char* in your example, there isn't much difference. The second form is usable after the loop exits, and only evaluates the initializer once. But as John says, most compilers will precalculate the initialization anyway.

There's an obvious difference if ptr gets re-assigned inside the loop (and if you don't reassign it, you should make it char* const ptr), in that the value will be kept from the previous iteration instead of reset.

Finally, non-POD types would have their constructor and destructor run for every loop iteration.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文