遍历数组在Java中的最快方法:循环变量VS增强的语句[复制]遍历数组在Java中的最快方法:循环变

2019-05-13 11:07发布

这个问题已经在这里有一个答案:

  • 是否有循环和for-each循环之间的性能差异? 17个回答

在Java中,它是通过更快的数组老式的方式进行迭代,

for (int i = 0; i < a.length; i++)
    f(a[i]);

或使用更简洁的形式,

for (Foo foo : a)
    f(foo);

对于一个ArrayList,答案是一样的吗?

当然,对于绝大部分的应用程序代码,答案是它并没有明显的差异,因此更简洁的形式应该被用于可读性。 不过我看上下文是重型技术计算,与必须进行数十亿次,所以即使一个微小的速度差可能最终会被显著操作。

Answer 1:

如果你通过一个数组循环,它不应该的问题 - 增强的for循环使用数组访问反正。

例如,考虑以下代码:

public static void main(String[] args)
{
    for (String x : args)
    {
        System.out.println(x);
    }
}

当与反编译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循环略偏设置代码,但他们基本上做同样的事情。 没有迭代器都参与其中。 此外,我希望他们得到即时编译甚至更多类似的代码。

建议:如果你真的认为它可能使一个显著的差异(它永远只能做,如果循环体是绝对微乎其微),那么你应该基准它与您的实际应用。 这是其唯一重要的情况。



Answer 2:

这在竞技场正视落在微优化 。 这其实并不重要。 从风格上我总是喜欢第二个,因为它更简洁,除非你需要其他的东西循环计数器。 而这远比这种微优化的更重要 :可读性。

话虽这么说,对于一个ArrayList不会有太大的差别,但在LinkedList将更加有效地与第二。



Answer 3:

衡量它。 在所有性能问题的答案可能取决于VM-版本,处理器,内存速度,高速缓存等,所以,你必须衡量它为您的特定平台。

个人而言,我更喜欢第二个变种,因为意图更加清晰。 如果性能成为一个问题,我可以在以后反正优化它 - 如果这代码真的是为整个应用程序的性能非常重要。



Answer 4:

对于一个LinkedList:

for(ClassOfElement element : listOfElements) {
  System.out.println(element.getValue());
}

有人回答之前:

是否有循环和for-each循环之间的性能差异?



Answer 5:

在一个阵列,或者收集了RandomAccess你可以做在速度的微小增加:

List<Object> list = new ArrayList<Object>();

for (int i=0, d=list.size(); i<d; i++) {
    something(list.get(i));
}

但我不会在一般的担心。 像这样的优化不会让超过0.1%的差异对你的代码。 尝试调用Java与-prof,看看你的代码实际上是消耗时间。



Answer 6:

更快的是使用fork-join框架的的ParallelArray(如果你有足够大的数据集)。



文章来源: Fastest way to iterate an Array in Java: loop variable vs enhanced for statement [duplicate]