2017-08-07 158 views
3

问题是,“我们可能期望method3运行得比method2快,为什么会这样?”但我不知道。看起来这两种方法都可以执行相同的操作。有人请赐教吗?for循环性能迭代

ArrayList<Person> method2(Person x, ArrayList<Person> people){ 
    ArrayList<Person> friends = new ArrayList<Person>(); 
    for (Person y : people) if (x.knows(y)) friends.add(y); 
    return friends; 
} 


ArrayList<Person> method3(Person x, ArrayList<Person> people){ 
    ArrayList<Person> friends = new ArrayList<Person>(); 
    for (int=0; i<people.size(); i++){ 
     Person y = people.get(i); 
     if (x.knows(y)) friends.add(y); 
    } 
    return friends; 
} 
+0

在现实世界中,99.99%的时间,这两种方法之间唯一有意义的区别是可读性。 2之间的性能差异取决于列表的大小,以及ArrayList如何实现get和getItorator方法,并且几乎不会影响;任何基于类实现的设计选择总是本质上是错误的(除非你需要挤出每一分性能,在这种情况下,你很可能会在较低的水平上编码) – Tezra

回答

4

“我们可以预期方法3跑得比较快方法2,这是为什么?”

它可能但差异应该是最小的,甚至不考虑作为选择一个或另一个的信息。

这两个方法与方差进行同样的事情:一个加强formethod2()和访问的Listget(int index)method3()经典for

编译代码method2()将导致使用迭代器,在运行时可能会稍微长一点执行但它应该没有显着差异。


例如:hasNext()迭代用于ArrayList进行一些检查和一些非常微小的计算:

public E next() { 
    checkForComodification(); 
    int i = cursor; 
    if (i >= size) 
     throw new NoSuchElementException(); 
    Object[] elementData = ArrayList.this.elementData; 
    if (i >= elementData.length) 
     throw new ConcurrentModificationException(); 
    cursor = i + 1; 
    return (E) elementData[lastRet = i]; 
} 

使用该get(int index)方法A for具有较少的计算:

public E get(int index) { 
    rangeCheck(index); 

    return elementData(index); 
} 
+0

我认为问题是要求学生认识'method2()'分配一个迭代器,但是通过现代JIT优化等,这样做不会以任何显着的方式减慢速度。 –

+0

@Silvio Mayolo你对教学问题是正确的。现在用迭代器编译的代码执行更多的计算。我更新以显示它。这些都是极端的未成年人,但这些都超过了get()方法。就我个人而言,我无法确认JVM在优化之后对其进行零处理。 – davidxxx

+0

@davidxxx你是对的,但在这种情况下,它只适用于仅使用people.size()只需一次并将值赋给变量(不需要为每个项调用size())。 –

5

不是这样。两种方法都将以几乎相同的速度运行。

要他们不会以完全相同的速度运行的程度,两件事情抱:

  1. 它不会让有点区别的是任意实用的场景。

  2. 您无法确定是否会运行得更快,它是method2还是method3