在循环之前声明变量和在循环中声明变量的区别是什么?

345

我一直想知道,在一般情况下,将一个临时变量在循环之前声明,相对于在循环内部重复声明,是否会有任何(性能)差异?以Java为例,以下是一个(毫无意义的)示例:

a) 循环之前声明:

double intermediateResult;
for(int i=0; i < 1000; i++){
    intermediateResult = i;
    System.out.println(intermediateResult);
}

b) 在循环内(重复)声明:

for(int i=0; i < 1000; i++){
    double intermediateResult = i;
    System.out.println(intermediateResult);
}
哪个更好,a 还是 b
我怀疑重复变量声明(例如 b)在理论上会创建更多开销,但编译器已经足够聪明,因此这并不重要。 例如 b 具有更紧凑的优点,并将变量的作用域限制在使用它的位置。 不过,我还是倾向于按照示例 a 编码。
编辑:我特别关注Java情况。

这在编写Android平台的Java代码时非常重要。Google建议对于时间关键的代码,将递增变量声明在for循环外部,就像在for循环内部一样,因为在那个环境中每次都会重新声明它。对于昂贵的算法,性能差异非常明显。 - aaroncarsonart
1
@AaronCarson,您能否提供谷歌此建议的链接? - Vitaly Zinchenko
【相关问题】C++中的同一个问题:c++ - 在循环内声明变量是好习惯还是坏习惯?- Stack Overflow - user202729
26个回答

0

这是更好的形式

double intermediateResult;
int i = byte.MinValue;

for(; i < 1000; i++)
{
intermediateResult = i;
System.out.println(intermediateResult);
}

1) 这样只声明一次变量,而不是每个循环都声明。 2) 赋值比其他选项更快。 3) 因此,最佳实践规则是在迭代之外进行任何声明。


0

这是一个有趣的问题。从我的经验来看,当你在讨论代码时,有一个终极问题需要考虑:

是否有任何理由需要将变量设为全局变量?

只声明一次全局变量,而不是在多个地方声明局部变量,这样做更好地组织了代码,并且需要的代码行数更少,因此这种方式是有意义的。然而,如果它只需要在一个方法中被声明为局部变量,那么我会在该方法中初始化它,以便清楚地表明该变量仅与该方法相关。如果您选择后者,请注意不要在初始化变量的方法之外调用该变量--否则您的代码将无法识别该变量并报告错误。

另外,顺带一提,即使它们的目的非常相似,也不要在不同的方法之间重复使用局部变量名称;这只会让人感到困惑。


1
我因为很多原因不同意...但是,我不会点踩...我尊重你的选择权。 - Grantly

0

当我想在退出循环后查看变量的内容时,我使用(A)。这只对调试有影响。当我想要更紧凑的代码时,我使用(B),因为它可以节省一行代码。


0
尝试在Go中进行相同的操作,并使用go tool compile -S与go 1.9.4比较编译器输出。 根据汇编器输出,没有任何差异。

0

A)比B)更保险……想象一下,如果您在循环中初始化结构而不是'int'或'float',那会怎样?

例如

typedef struct loop_example{

JXTZ hi; // where JXTZ could be another type...say closed source lib 
         // you include in Makefile

}loop_example_struct;

//then....

int j = 0; // declare here or face c99 error if in loop - depends on compiler setting

for ( ;j++; )
{
   loop_example loop_object; // guess the result in memory heap?
}

你肯定会面临内存泄漏的问题!因此,我认为选择'A'更安全,而'B'容易积累内存,特别是在使用闭源库时。你可以在Linux上使用'Valgrind'工具,特别是子工具'Helgrind'来进行检查。

-1

即使我知道我的编译器足够聪明,我也不想依赖它,而会使用a)变量。

只有在您迫切需要在循环体后使中间结果不可用时,b)变量才对我有意义。但无论如何,我都无法想象出这样绝望的情况....

编辑:Jon Skeet提出了一个非常好的观点,表明循环内部的变量声明可能会产生实际的语义差异。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接