Java中循环的局部变量初始化最有效的方法是什么?

时间:2012-09-27 07:52:51

标签: java performance variables loops

  

可能重复:
  Declaring variables inside or outside of a loop

请考虑这两个Java代码示例:

// 1st sample
for (Item item : items) {
    Foo foo = item.getFoo();
    int bar = item.getBar();
    // do smth with foo and bar
}

// 2nd sample
Foo foo;
int bar;
for (Item item : items) {
    foo = item.getFoo();
    bar = item.getBar();
    // do smth with foo and bar
}

样品之间的性能/内存消耗是否有任何差异?如果是,那么它是否依赖于句柄的类型(对象与原语)?

2 个答案:

答案 0 :(得分:8)

它在生成的字节代码方面有所不同,但在性能方面没有差异。

更重要的是使代码尽可能简单,自包含和可维护。出于这个原因,我更喜欢第一个例子。

BTW:更简单的代码经常被更好地优化,因为它更容易让JIT尽可能地进行优化。令人困惑的代码也会混淆JIT,它会阻止使用优化。

如果你使用ASMifierClassVisitor以可读的形式转储原始字节代码(并且可以转回原始字节代码)你会看到javap掩盖了一些细节,不那么重要

如果我比较(在左下方)951字节长。

List<Item> items = new ArrayList<Item>();

Foo foo;
int bar;
for (Item item : items) {
    foo = item.getFoo();
    bar= item.getBar();
    // do something with foo and bar
}

(右下方)和935字节长。

List<Item> items = new ArrayList<Item>();

for (Item item : items) {
    Foo foo = item.getFoo();
    int bar = item.getBar();
    // do something with foo and bar
}

您至少可以看到调试行号必须不同,但也有一些代码不同,以及以不同顺序定义的局部变量,并给出不同的分配编号。

enter image description here

你可以right click =&gt; View Image可以更好地查看图片。

答案 1 :(得分:1)

如果您担心第二个示例中的泄漏范围,您还可以通过将其放在一个块中来限制范围:

{
    Foo foo;
    int bar;
    for (Item item : items) {
        foo = item.getFoo();
        bar = item.getBar();
        // do smth with foo and bar
    }
}