【问题标题】:Which performs better : for each or iterator in LinkedList?哪个性能更好:对于 LinkedList 中的每个或迭代器?
【发布时间】:2014-11-03 22:13:57
【问题描述】:

我一直在检查 for eachIterator 在通过程序遍历 LinkedList 时的性能:

public class ListTraversePerformance {
    public static void main(String... args){
        List<String> list = new LinkedList<String>();
        for(int i=0;i<100000;i++){
            list.add("Any String" + i);
        }
        Iterator i = list.iterator();
        String x;
        long t1 = System.currentTimeMillis();
        for(String j: list){
             x = j;

        }
        long t2 = System.currentTimeMillis();
        while(i.hasNext()){ 
            x= (String)i.next();

        }
        long t3 = System.currentTimeMillis();
        System.out.print((t2-t1) + "  " + (t3-t2));
    }
}

我得到的输出每次都不同,即有时第一个循环运行得很快,有时第二个。

我的问题:

我认为 for each 循环的运行速度应该比第二个 Iterator 慢。我认为在for each 循环中,与O(n)Iterator 的复杂性相比,链表每次都应该从头开始遍历,使其复杂性O(n^2)。我对么?如果是,那么为什么结果不符合我的预期......

【问题讨论】:

  • LinkedList 总是从起始节点遍历到结束。
  • 不,你不正确。 foreach 循环不需要每次都从头开始迭代。
  • @JunedAhsan 我有一个想法,我的问题是为什么 for each 循环运行不慢。
  • @sagar 不同的执行会给你不同的执行时间,即使对于同一段代码,取决于当前的 cpu 状态。简而言之,两种情况之间没有时间复杂度差异,因为链表总是从头到尾遍历。
  • k,我明白了,谢谢.. @JunedAhsan

标签: java collections foreach linked-list iterator


【解决方案1】:

这两者几乎是等价的,而且它们都是 O(n),因为每个元素只被迭代一次。两者都不重复迭代。

for each 循环在底层使用了一个迭代器。它是对实现Iterable 的对象进行迭代的语法糖,这反过来又创建了一个迭代器。因此,当我说这两者几乎相同时,我的意思是字面意思。

微基准测试很难正确进行。最大的问题是我们最终认为我们正在为一件事计时,但实际上我们正在计时另一件事。并且需要大量挖掘才能将其全部分解以了解真正发生的事情。阅读以下相关帖子的答案,它将解释为什么时代变化如此之大,以及如何使用它。 Why are floating point operations much faster with a warmup phase?。该问题的 SO 与您对基准的观察几乎相同,仅使用浮点运算而不是列表迭代。

快速总结是 1) JVM 通过解释器开始执行代码,并动态优化代码的热点区域,2) GC 和其他后台进程可能会干扰,有些可能在 JVM 中,有些可能在外部JVM。

【讨论】:

  • @sagar 已在该问题的答案中进行了解释,我已在此问题中对该帖子进行了非常快速的总结,但我想避免在此处重复该帖子。
猜你喜欢
  • 2017-08-06
  • 1970-01-01
  • 1970-01-01
  • 2011-11-24
  • 1970-01-01
  • 2012-07-20
  • 2010-11-16
  • 2011-06-13
  • 2013-04-22
相关资源
最近更新 更多