2

第一个示例在 Java/Android 和 Java 中生成的代码是否比第二个更高效?

至少第一个例子不能比第二个慢,我想..

我不在乎变量 v 在第一个示例中可能会存在更长的时间,也许会在更长的时间内吃掉内存。

当然,如果您有更复杂的代码和多个内部块,那么第二种方式确实更具可读性。这也不是这里的问题。

MyType v;
for(int i=0;i<bigCount;++i)
{
  v = <value produced for i>;
  //do something with v
}


for(int i=0;i<bigCount;++i)
{
  MyType v = <value produced for i>;
  //do something with v
}
4

3 回答 3

2

我会选择第二个选项,因为v变量范围在for循环内。它不需要在外面的任何地方使用。

这样,创建和分配给的对象就可以v更早地进行垃圾回收。或者至少最后一个将比第一段代码更快地符合条件。

于 2013-02-23T13:14:23.700 回答
1

我创建了一个最小的例子:

public void option1() {
    String s;
    for (int i = 0; i < foo; i++) {
        s = String.valueOf(i);
    }
}

public void option2() {
    for (int i = 0; i < foo; i++) {
        String s = String.valueOf(i);
    }
}

并发现生成的字节码对于两者都是相同的:

option1()

 0 iconst_0
 1 istore_2
 2 goto 13 (+11)
 5 iload_2
 6 invokestatic #17 <java/lang/String/valueOf(I)Ljava/lang/String;>
 9 astore_1
10 iinc 2 by 1
13 iload_2
14 aload_0
15 getfield #23 <MethodTest/foo I>
18 if_icmplt 5 (-13)
21 return

option2()

 0 iconst_0
 1 istore_1
 2 goto 13 (+11)
 5 iload_1
 6 invokestatic #17 <java/lang/String/valueOf(I)Ljava/lang/String;>
 9 astore_2
10 iinc 1 by 1
13 iload_1
14 aload_0
15 getfield #23 <MethodTest/foo I>
18 if_icmplt 5 (-13)
21 return

我的猜测是,如果编译器看到,在循环之前创建的变量永远不会在循环之后使用,它只是将它的定义拉到循环中。所以在你的情况下,两者都不是更有效的。所以选择更易读的(option2())。

于 2013-02-23T13:40:08.850 回答
0

为了防止多次分配,您可以像这样在它自己的范围内关闭变量:

{
  MyType v;
  for(int i=0;i<bigCount;++i)
  {
    v = <value produced for i>;
    //do something with v
  }
}

v将由GC该块之后收集

于 2013-02-23T13:21:53.260 回答