在Java中,以老式的方式遍历数组是否更快,
for (int i = 0; i < a.length; i++) f(a[i]);
或者使用更简洁的形式,
for (Foo foo : a) f(foo);
对于ArrayList,答案是否相同?
当然,对于大量的应用程序代码,答案是没有明显的区别,因此应使用更简洁的形式以提高可读性。但是,我正在研究的上下文是重型技术计算,必须执行数十亿次操作,因此即使很小的速度差异也可能会变得非常重要。
如果您要遍历数组,没关系-增强的for循环无论如何都会使用数组访问。
例如,考虑以下代码:
public static void main(String[] args) { for (String x : args) { System.out.println(x); } }
当反编译时,javap -c Test我们得到(用于main方法):
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
现在将其更改为使用显式数组访问:
public static void main(String[] args) { for (int i = 0; i < args.length; i++) { System.out.println(args[i]); } }
这反编译为:
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
增强的for循环中还有更多设置代码,但它们基本上是在做相同的事情。不涉及迭代器。此外,我希望他们会被JITted甚至更多类似的代码。
建议:如果你真的认为它可能使一个显著差异(这只会 永远 做,如果循环体是绝对微乎其微),那么你应该基准它与您的实际应用。那是唯一重要的情况。