6

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

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
    */
}

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

谢谢,博达赛多。

4

6 回答 6

13

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

于 2010-07-28T13:30:45.530 回答
2

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

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

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

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

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

于 2010-07-28T14:27:32.717 回答
1

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

于 2010-07-28T13:30:17.217 回答
0

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

于 2010-07-28T13:32:26.040 回答
0

作为“C”程序中的个人约定,我喜欢将变量声明放在函数顶部、文件顶部或通用 .h 文件中。如果我开始将声明隐藏在代码中,则可能会造成混淆并且容易忘记变量范围,从而导致不良后果。

于 2010-07-28T13:34:14.787 回答
0

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

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

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

于 2010-07-28T13:34:32.640 回答