如果有的话,下面两个循环之间的性能差异是什么?
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();
}
当前回答
通过变量名称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循环之前和之后,都要对软件进行良好的基准测试。
通过变量名称objectArrayList,我假设它是java.util.ArrayList的一个实例。在这种情况下,性能差异是不明显的。
另一方面,如果它是java.util的实例。LinkedList,第二种方法会慢得多,因为list# get(int)是一个O(n)操作。
因此,第一种方法总是首选的,除非循环中的逻辑需要索引。
对性能的影响基本上是微不足道的,但也不是零。如果你看看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使你的代码的意图更清晰,这通常比非常小的速度改进更受欢迎——如果有的话。
每当我看到一个索引循环,我必须解析它一段时间,以确保它做什么,我认为它做,例如,它是否从零开始,它是否包括或排除终点等?
我的大部分时间似乎都花在了阅读代码(我写的或别人写的)上,而清晰度几乎总是比性能更重要。现在很容易忽略Hotspot的性能,因为Hotspot做得非常出色。
以下是Android开发团队对两者差异的简要分析:
https://www.youtube.com/watch?v=MZOf3pOAM6A
The result is that there is a difference, and in very restrained environments with very large lists it could be a noticeable difference. In their testing, the for each loop took twice as long. However, their testing was over an arraylist of 400,000 integers. The actual difference per element in the array was 6 microseconds. I haven't tested and they didn't say, but I would expect the difference to be slightly larger using objects rather than primitives, but even still unless you are building library code where you have no idea the scale of what you will be asked to iterate over, I think the difference is not worth stressing about.