在循环内部或外部声明一个对象?

Yuv*_*dam 55 java performance

以下代码段是否存在任何性能损失?

for (int i=0; i<someValue; i++)
{
    Object o = someList.get(i);
    o.doSomething;
}
Run Code Online (Sandbox Code Playgroud)

或者这段代码实际上更有意义吗?

Object o;
for (int i=0; i<someValue; i++)
{
    o = someList.get(i);
    o.doSomething;
}
Run Code Online (Sandbox Code Playgroud)

如果在字节代码中这两个是完全等效的,那么显然第一种方法在样式方面看起来更好,但我想确保这种情况.

Dav*_*kle 47

在今天的编译器中,没有.我在最小的范围内声明对象,因为它对下一个人来说更具可读性.


Dan*_*ton 16

引用可能引用Hoare的Knuth:

过早优化是万恶之源.

通过在循环外定义变量,编译器是否会产生稍微快一点的代码是有争议的,我想它不会.我它会产生相同的字节码.

将此与您可能通过使用循环声明正确确定变量范围的错误数量进行比较...


Mar*_*olk 10

在循环中声明Object o没有性能损失.编译器生成非常相似的字节码并进行正确的优化.

请参阅文章神话 - 在循环内定义循环变量对类似示例的性能不利.


Rol*_*der 7

您可以使用javap -c反汇编代码并检查编译器实际发出的内容.在我的设置(使用eclipse编译的java 1.5/mac)中,循环的字节码是相同的.


Meh*_*ari 5

第一个代码更好,因为它将o变量的范围限制为for块.从性能的角度来看,它可能对Java没有任何影响,但它可能在较低级别的编译器中.如果你做第一个,他们可能会把变量放在寄存器中.

事实上,有些人可能会认为如果编译器很笨,那么第二个片段在性能方面会更好.这是一些导师在大学时告诉我的,我嘲笑他这个建议!基本上,编译器在方法开始时只在方法的局部变量上分配一次内存(通过调整堆栈指针)并在方法结束时释放它(再次通过调整堆栈指针,假设它不是C++)或者它没有任何析构函数被调用).因此,方法中的所有基于堆栈的局部变量都会立即分配,无论它们在何处被声明,以及它们需要多少内存.实际上,如果编译器是愚蠢的,那么在性能方面没有区别,但如果它足够聪明,那么第一个代码实际上可以更好,因为它' ll帮助编译器理解变量的范围和生命周期!顺便说一下,如果它真的很聪明,那么性能应该没有绝对差别,因为它可以推断实际范围.

当然,使用对象的构造new与仅仅声明它完全不同.

我认为可读性对性能更重要,从可读性的角度来看,第一个代码肯定更好.