rwa*_*ace 28 java iteration performance
在Java中,以老式的方式迭代数组是否更快,
for (int i = 0; i < a.length; i++)
f(a[i]);
Run Code Online (Sandbox Code Playgroud)
或者使用更简洁的表格,
for (Foo foo : a)
f(foo);
Run Code Online (Sandbox Code Playgroud)
对于ArrayList,答案是否相同?
当然,对于大量的应用程序代码,答案是它没有明显的区别,因此应该使用更简洁的表单来提高可读性.然而,我正在研究的背景是重型技术计算,必须执行数十亿次操作,因此即使很小的速度差异也可能最终显着.
Jon*_*eet 55
如果你在数组中循环,那应该没关系 - 增强的for循环无论如何都使用了数组访问.
例如,考虑以下代码:
public static void main(String[] args)
{
for (String x : args)
{
System.out.println(x);
}
}
Run Code Online (Sandbox Code Playgroud)
当javap -c Test我们得到反编译时(对于main方法):
public static void main(java.lang.String[]);
Code:
0: aload_0
1: astore_1
2: aload_1
3: arraylength
4: istore_2
5: iconst_0
6: istore_3
7: iload_3
8: iload_2
9: if_icmpge 31
12: aload_1
13: iload_3
14: aaload
15: astore 4
17: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
20: aload 4
22: invokevirtual #3; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
25: iinc 3, 1
28: goto 7
31: return
Run Code Online (Sandbox Code Playgroud)
现在更改它以使用显式数组访问:
public static void main(String[] args)
{
for (int i = 0; i < args.length; i++)
{
System.out.println(args[i]);
}
}
Run Code Online (Sandbox Code Playgroud)
这反编译为:
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: iload_1
3: aload_0
4: arraylength
5: if_icmpge 23
8: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
11: aload_0
12: iload_1
13: aaload
14: invokevirtual #3; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
17: iinc 1, 1
20: goto 2
23: return
Run Code Online (Sandbox Code Playgroud)
在增强的for循环中有更多的设置代码,但它们基本上做同样的事情.没有涉及迭代器.此外,我希望他们能够获得更多相似代码的JIT.
建议:如果你真的认为它可能使一个显著差异(这只会永远做,如果循环体是绝对微乎其微),那么你应该基准它与您的实际应用.这是唯一重要的情况.
测量它.所有性能问题的答案可能取决于VM版本,处理器,内存速度,缓存等.因此,您必须针对您的特定平台进行测量.
我个人更喜欢第二种变体,因为意图更清晰.如果性能成为一个问题,我可以在以后优化它 - 如果该代码对整个应用程序的性能非常重要.