for循环性能迭代
问题是,“我们可能期望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;
}
“我们可以预期方法3跑得比较快方法2,这是为什么?”
它可能但差异应该是最小的,甚至不考虑作为选择一个或另一个的信息。
这两个方法与方差进行同样的事情:一个加强for
的method2()
和访问的List
与get(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);
}
我认为问题是要求学生认识'method2()'分配一个迭代器,但是通过现代JIT优化等,这样做不会以任何显着的方式减慢速度。 –
@Silvio Mayolo你对教学问题是正确的。现在用迭代器编译的代码执行更多的计算。我更新以显示它。这些都是极端的未成年人,但这些都超过了get()方法。就我个人而言,我无法确认JVM在优化之后对其进行零处理。 – davidxxx
@davidxxx你是对的,但在这种情况下,它只适用于仅使用people.size()只需一次并将值赋给变量(不需要为每个项调用size())。 –
不是这样。两种方法都将以几乎相同的速度运行。
要他们不会以完全相同的速度运行的程度,两件事情抱:
它不会让有点区别的是任意实用的场景。
您无法确定是否会运行得更快,它是
method2
还是method3
。
在现实世界中,99.99%的时间,这两种方法之间唯一有意义的区别是可读性。 2之间的性能差异取决于列表的大小,以及ArrayList如何实现get和getItorator方法,并且几乎不会影响;任何基于类实现的设计选择总是本质上是错误的(除非你需要挤出每一分性能,在这种情况下,你很可能会在较低的水平上编码) – Tezra