在这三个来源之间,效率方面是否存在差异?
for (int i=0; i<N; i++)
int j = whatever();
和
int j;
for (int i=0; i<N; i++)
j = whatever();
和
int i, j;
for (i=0; i<N; i++)
j = whatever();
感谢。
PS:显然我的问题不是参考变量的范围而是仅仅考虑循环的效率,特别是在前两种情况下,变量j被声明为一次而非N次。
答案 0 :(得分:7)
声明变量对性能没有影响。编译代码后,JIT足够智能,可以预先分配局部变量。
从技术上讲,限制变量的范围可以提高性能,因为它不需要在不再需要变量之后保留变量,但我怀疑JIT也足够聪明,可以解决这个问题。
答案 1 :(得分:3)
声明变量会影响编译时间,而不会影响运行时间。局部变量将在堆栈中占用的空间在编译时分配,因此运行时不会受到影响。
受影响的是可读性:通常,最好将变量声明为接近使用它们的位置,并将它们保持在程序允许的范围内。从这个意义上讲,您的第一个代码段是最好的。
使用代码段2或3的唯一原因是在循环完成后需要变量i
或j
的值时,例如,查找何时执行break
语句。从您的示例中无法判断是否是这种情况。
答案 2 :(得分:3)
编译器优化代码后应该没有区别。
如果您在默认优化已关闭的调试模式下运行, 如果在循环范围内声明变量,则效率低于在循环范围外声明变量。
在这种情况下,对于循环的每次迭代,代码将在堆栈上为变量创建空间,并且在迭代之后它将被丢弃。这效率稍低。
但是对于循环变量(i),你在for循环或内部之前声明它并不重要,因为它只会在堆栈上分配一次。
因此,在调试模式下结束时,2和3的性能优于1。 在发布模式下,所有3都是相同的。
答案 3 :(得分:2)
没有。您需要了解代码是否已编译为字节码,然后在Java虚拟机(JVM)上运行,它将字节码转换为机器代码并在即时(JIT)上进行优化。
许多简单的事情如多变量声明在编译到字节码或JIT期间都被优化。
我希望我可以将你与一篇好文章联系起来,但我没有考虑到这一点。
答案 4 :(得分:1)
他们实际上都是一样的。它们之间的唯一区别在于,在第二个示例中,一个变量的作用域位于循环之外,而在第二个示例中,两个变量的作用域都在循环之外。在你的第一个例子中,这两个变量都不能在循环之外访问,这使得它通常是在循环中处理变量的更好方法,除非有理由在它们之外可以访问它们。
int x = 0;
只需要JVM将原始32位值0分配给与x
关联的内存中的位置。但是,在这种情况下使用自动装箱会很有趣,因为Integer x = 0
要求JVM实例化一个有更多资源要求的新对象。
答案 5 :(得分:0)
在第一个示例中,变量将是initializad N
次。
基本上,三个例子之间没有显着差异。取决于您是否需要更广范围内的j
变量。这是主要区别。
答案 6 :(得分:0)
正如写的?否。
是否存在区别重要的情况?是。
这些情况经常出现在编译器无法为您处理的情况下吗?否。
在任何一种情况下,最好的办法是测试它。回答(和帮助)“为什么这比那个慢?”
更容易回答答案 7 :(得分:0)
三个例子在效率方面没有区别。但是根据编码标准,你应该在只需要时声明变量。 Alsothere在变量的可见性方面存在差异。让我解释一下
<强>选项1 强>
for (int i=0; i<N; i++)
int j = whatever();
此处变量j的范围仅在for循环中
选项2
int j;
for (int i=0; i<N; i++)
j = whatever();
这里j在for循环的内部和外部都是可见的但是我只能在for循环的范围内看到
选项3
int i, j;
for (i=0; i<N; i++)
j = whatever();
这里变量i和j在两个地方都可见,即for循环的外部和内部
答案 8 :(得分:0)
除非您执行此代码片段数百万次,否则答案是选择最易读(因此最易维护)源代码。
即使上述技术之一显着加快,大多数代码(超过90%)也不会经常执行,因此其速度与整体程序性能无关。专注于编写可读,易懂和可维护的代码。 然后您可以优化10%(或更少)真正导致性能瓶颈的代码。