如果有的话,下面两个循环之间的性能差异是什么?
for (Object o: objectArrayList) {
o.DoSomething();
}
and
for (int i=0; i<objectArrayList.size(); i++) {
objectArrayList.get(i).DoSomething();
}
如果有的话,下面两个循环之间的性能差异是什么?
for (Object o: objectArrayList) {
o.DoSomething();
}
and
for (int i=0; i<objectArrayList.size(); i++) {
objectArrayList.get(i).DoSomething();
}
当前回答
摘自Joshua Bloch的《Effective Java》第46条:
The for-each loop, introduced in release 1.5, gets rid of the clutter and the opportunity for error by hiding the iterator or index variable completely. The resulting idiom applies equally to collections and arrays: // The preferred idiom for iterating over collections and arrays for (Element e : elements) { doSomething(e); } When you see the colon (:), read it as “in.” Thus, the loop above reads as “for each element e in elements.” Note that there is no performance penalty for using the for-each loop, even for arrays. In fact, it may offer a slight performance advantage over an ordinary for loop in some circumstances, as it computes the limit of the array index only once. While you can do this by hand (Item 45), programmers don’t always do so.
其他回答
对性能的影响基本上是微不足道的,但也不是零。如果你看看JavaDoc的RandomAccess接口:
根据经验,一个列表 实现应该实现这个 的典型实例 这个类,这个循环: For (int i=0, n=list.size();I < n;我+ +) list.get(我); 运行速度比这个循环快: for(迭代器i=list.iterator();i.hasNext (); i.next ();
for-each循环使用version with iterator,以ArrayList为例,for-each循环不是最快的。
奇怪的是,没有人提到显而易见的——foreach分配内存(以迭代器的形式),而普通的for循环不分配任何内存。对于Android游戏来说,这是个问题,因为这意味着垃圾收集器将周期性地运行。在游戏中,你不希望垃圾回收器运行……永远。所以不要在你的绘制(或渲染)方法中使用foreach循环。
通过变量名称objectArrayList,我假设它是java.util.ArrayList的一个实例。在这种情况下,性能差异是不明显的。
另一方面,如果它是java.util的实例。LinkedList,第二种方法会慢得多,因为list# get(int)是一个O(n)操作。
因此,第一种方法总是首选的,除非循环中的逻辑需要索引。
所有这些循环都是一样的,我只是想在发表我的观点之前展示一下。
首先,循环List的经典方法:
for (int i=0; i < strings.size(); i++) { /* do something using strings.get(i) */ }
其次,这是首选的方法,因为它更不容易出错(你有多少次做过“哎呀,在这些循环中循环中混合变量i和j”的事情?)
for (String s : strings) { /* do something using s */ }
第三,微优化for循环:
int size = strings.size();
for (int i = -1; ++i < size;) { /* do something using strings.get(i) */ }
现在真正的两美分:至少当我测试这些时,第三个是最快的,当计算每种类型的循环所花费的毫秒数时,其中一个简单的操作重复了数百万次——这是在Windows上使用Java 5和jre1.6u10,如果有人感兴趣的话。
While it at least seems to be so that the third one is the fastest, you really should ask yourself if you want to take the risk of implementing this peephole optimization everywhere in your looping code since from what I've seen, actual looping isn't usually the most time consuming part of any real program (or maybe I'm just working on the wrong field, who knows). And also like I mentioned in the pretext for the Java for-each loop (some refer to it as Iterator loop and others as for-in loop) you are less likely to hit that one particular stupid bug when using it. And before debating how this even can even be faster than the other ones, remember that javac doesn't optimize bytecode at all (well, nearly at all anyway), it just compiles it.
如果你喜欢微观优化,或者你的软件使用了很多递归循环,那么你可能会对第三种循环感兴趣。只需要记住,在更改for循环之前和之后,都要对软件进行良好的基准测试。
摘自Joshua Bloch的《Effective Java》第46条:
The for-each loop, introduced in release 1.5, gets rid of the clutter and the opportunity for error by hiding the iterator or index variable completely. The resulting idiom applies equally to collections and arrays: // The preferred idiom for iterating over collections and arrays for (Element e : elements) { doSomething(e); } When you see the colon (:), read it as “in.” Thus, the loop above reads as “for each element e in elements.” Note that there is no performance penalty for using the for-each loop, even for arrays. In fact, it may offer a slight performance advantage over an ordinary for loop in some circumstances, as it computes the limit of the array index only once. While you can do this by hand (Item 45), programmers don’t always do so.