我在这里读到 * 增强的for循环 * 比普通的 *for循环 * 更高效:
http://developer.android.com/guide/practices/performance.html#foreach
当我搜索他们效率的差异时,我发现的只是:对于普通的for循环,我们需要额外的步骤来找出数组的长度或大小等。
for(Integer i : list){
....
}
int n = list.size();
for(int i=0; i < n; ++i){
....
}
但是这是唯一的原因吗,增强的for循环比普通的for循环好?在这种情况下,最好使用普通的 *for循环 *,因为理解增强的 *for循环 * 稍微有点复杂。
查看以下有趣的问题:http://www.coderanch.com/t/258147/java-programmer-SCJP/certification/Enhanced-Loop-Vs-Loop
有谁能解释一下这两种for循环的内部实现,或者解释一下使用增强的 *for循环 * 的其他原因吗?
7条答案
按热度按时间pgccezyw1#
说增强的for循环更高效有点过于简单化了,它 * 可以 * 是这样,但在很多情况下它几乎和老式循环完全一样。
首先要注意的是,对于集合,增强的for循环使用
Iterator
,所以如果你使用Iterator
手动迭代集合,那么你应该得到与增强的for循环几乎相同的性能。增强的for循环比 * 天真实现的 * 传统循环更快的一个地方是这样的:
在这种情况下,环路1将比环路2和环路3都慢,因为它必须在每次迭代中(部分地)遍历列表以找到位置
i
处的元素。然而,循环2和3将仅在列表中进一步步进一个元素,由于使用了Iterator
,循环2和循环3也将具有几乎相同的性能,因为循环3几乎完全是编译器在循环2中编写代码时生成的结果。mznpcxlj2#
我今天做了一个小实验,对上面提到的几点感到很惊讶,所以我做的是在链表中插入一定数量的元素,然后用上面提到的三种方法迭代:1)使用高级for循环2)使用迭代器3)使用简单循环和get()
我想像你们这样的程序员可以通过看代码更好地理解我做了什么。
结果与我预期的不一样。以下是3种情况下所用时间的图表。x1c 0d1x
Y轴-经过时间X轴-测试用例
| 测试用例|输入|
| - ------|- ------|
| 1个|10个输入|
| 第二章|30个输入|
| 三个|50个输入|
| 四个|100个输入|
| 五个|150个输入|
| 六个|300个输入|
| 七|500个输入|
| 八个|1000个输入|
| 九|2000项投入|
| 十个|5000个输入|
| 十一|10000个输入|
| 十二|10万个输入|
在这里你可以看到简单的循环执行方式比其他更好。如果你发现上面的代码中有任何错误,请回复,我会再次检查。我会在通过字节码挖掘后进一步更新,看看引擎盖下发生了什么。我很抱歉这么长的回应,但我喜欢描述。菲利普
y1aodyip3#
我读到增强的for循环比普通的for循环更有效。
实际上,有时它的效率较低的程序,但大多数时候是完全一样的。
这对开发人员来说更有效率,而开发人员通常要重要得多
在遍历集合时,for-each循环特别有用。
更容易编写为(但执行的操作与相同,因此对程序来说效率并不高)
当通过索引访问可随机访问的集合时,使用“old”循环稍微更有效一些。
在集合上使用for-each循环总是使用Iterator,这对于随机访问列表来说效率稍低。
AFAIK,使用for-each循环对程序来说从来都不是更有效的,但是就像我说的,开发人员的效率通常要重要得多。
6rqinv9w4#
for-each使用Iterator接口,我怀疑它是否比“旧”风格更有效,Iterator还需要检查列表的大小。
主要是为了可读性。
对于非随机访问的集合,如LinkedList,它应该更快,但这样的比较是不公平的。无论如何,你不会习惯于第二个实现(索引访问很慢)。
brjng4g35#
foreach循环与此类循环一样高效:
因为它们是严格等价的
如果使用循环访问列表
那么foreach循环的性能和你的循环相当,但是只针对ArrayList,对于LinkedList,你的循环性能会很差,因为在每次迭代中,它都要遍历列表中的所有节点,直到到达第
i
个元素。foreach循环(或者基于迭代器的循环,这是相同的),没有这个问题,因为迭代器保持对当前节点的引用,并且在每次迭代时简单地转到下一个节点。这是最好的选择,因为它对所有类型的列表都能很好地工作。它也更清楚地表达了意图,并且更安全,因为你不会冒险在循环中递增索引。或者在嵌套循环的情况下使用错误的索引。
whhtz7ly6#
所有的答案都是好的,我认为不需要更多的答案,但我只想指出:
增强的for语句只能用于
obtain array elements
它不能用于**
modify elements
。如果程序需要修改元素,请使用传统的counter-controlled
for
语句。看一看
我们不能使用
enhanced for
语句,因为我们是modifying the array’s elements
。4ktjp1zp7#
来自有效Java:
循环数组的标准习惯用法不一定会导致冗余检查,现代JVM实现优化了它们。
但是Josh Bloch没有描述JVM如何优化它们。