对集合使用for each循环和Iterator的效率问题

xieyaa 2008-09-29 01:00:13
RT,java中使用这两种方法哪个的效率高。还有,和普通的for循环比起来,哪个效率更高。
...全文
3168 35 打赏 收藏 转发到动态 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
hjf520p 2012-03-26
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 lzheng2001 的回复:]
12楼不知道想表达什么, 你想说while比for 效率高吗?

结论是这样的,
1.for 与 while 性能是一样的,这个很多人都测试过了.

2. 另外 foreach 与 for + iterator 也是一样的,为什么一样上面已经说了,编译器最终把foreach编译成for + iterator,而且已经测试过了,事实跟理论一致.

3.至于LinkedList为什么这么……
[/Quote]


这个可以顶下!
wei980267563 2011-12-31
  • 打赏
  • 举报
回复
楼上全是大神,学习了!
杀猪剑客 2011-07-30
  • 打赏
  • 举报
回复
底层实现一样!
BatiTan 2009-07-02
  • 打赏
  • 举报
回复
领教了..不错
以前都不怎么注重底层实现
今天使用,学习了不少东西
不能飞的肥燕 2009-06-03
  • 打赏
  • 举报
回复
写段程序测试下:
public void testForEach() {
List<String> list = new ArrayList<String>();
int startNumber = 2;
for (int i = 10; i < 25; i++) {
double maxSize = Math.pow(startNumber, i);
for (int index = 0; index < maxSize; index++) {
list.add("");
}
Long start = System.currentTimeMillis();
for (int jj = 0; jj < maxSize; jj++) {
String result = list.get(jj);
}
Long end = System.currentTimeMillis();
long total1 = (end - start);

start = System.currentTimeMillis();
for (String result : list) {

}
end = System.currentTimeMillis();
long total2 = (end - start);
System.out.println(i + ": totalSzie: " + maxSize + ", and get took: "
+ total1 + ", while forEach took: " + total2);
list.clear();
}
}

结果如下:
10: totalSzie: 1024.0, and get took: 0, while forEach took: 0
11: totalSzie: 2048.0, and get took: 0, while forEach took: 0
12: totalSzie: 4096.0, and get took: 0, while forEach took: 0
13: totalSzie: 8192.0, and get took: 0, while forEach took: 0
14: totalSzie: 16384.0, and get took: 0, while forEach took: 0
15: totalSzie: 32768.0, and get took: 15, while forEach took: 0
16: totalSzie: 65536.0, and get took: 0, while forEach took: 0
17: totalSzie: 131072.0, and get took: 0, while forEach took: 0
18: totalSzie: 262144.0, and get took: 0, while forEach took: 15
19: totalSzie: 524288.0, and get took: 0, while forEach took: 31
20: totalSzie: 1048576.0, and get took: 15, while forEach took: 32
21: totalSzie: 2097152.0, and get took: 31, while forEach took: 79
22: totalSzie: 4194304.0, and get took: 62, while forEach took: 141
xyaoyuan 2009-06-03
  • 打赏
  • 举报
回复
学习了,长见识
ZangXT 2008-09-30
  • 打赏
  • 举报
回复
呵呵
lzheng2001 2008-09-30
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 ZangXT 的回复:]
我们没有冲突啊 ,呵呵
[/Quote]
哈哈,之前是笔误,应该是17楼, 你还提醒我用反编译分析呢,谢谢指教.
ZangXT 2008-09-30
  • 打赏
  • 举报
回复
我们没有冲突啊 ,呵呵
lzheng2001 2008-09-30
  • 打赏
  • 举报
回复
我运行的结果大多数情况下Iterator比foreach 快10ms左右, 有时候foreach会快一点, 我认为这点偏差对于我们的实际应用可以忽略不计. 根本不用理会.
lzheng2001 2008-09-30
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 ZangXT 的回复:]
12楼有什么问题吗?

只是后面怀疑了17楼的测试结果:foreach比Iterator快

楼上想说什么?
[/Quote]

我不是说了效率应该是一样的吗? 即使完全代码一样,你能保证你的电脑每次运行出同一个结果?? 事实上每次运行都会有一点点偏差. 哪怕完全一样的代码.
ZangXT 2008-09-30
  • 打赏
  • 举报
回复
12楼有什么问题吗?

只是后面怀疑了17楼的测试结果:foreach比Iterator快

楼上想说什么?
lzheng2001 2008-09-30
  • 打赏
  • 举报
回复
12楼不知道想表达什么, 你想说while比for 效率高吗?

结论是这样的,
1.for 与 while 性能是一样的,这个很多人都测试过了.

2. 另外 foreach 与 for + iterator 也是一样的,为什么一样上面已经说了,编译器最终把foreach编译成for + iterator,而且已经测试过了,事实跟理论一致.

3.至于LinkedList为什么这么长时间, 我在6楼已经说得很清楚了. 所以说for + get(i) 方法不够"通用"

4. foreach(for + iterator) 与 for + get(i) 性能差别很少(6楼已经说过了),iterator因为对所有集合效率几乎一样,所以很通用, 如果你的程序是面向接口的,一般就得用比较通用的iterator, 绝大多数情况下,我们都不必介意效率有那么一点儿差别, 我们需要知道有这么一点儿差别就是了.

以下对5000000条记录的ArrayList的测试结果,已经运行了十几次,每次结果差不多:
1.for + get(i)方法: 94
2.Iterator(foreach)方法:265
3.While + get(i)方法:94
4.for iterator方法:281


package myTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.SortedMap;
import java.util.Vector;

public class Test {
public static void main(String[] args)
{

List<Integer> list = new ArrayList<Integer>();
for(int i=0;i<5000000 ;i++){
list.add(11);
}


int size= list.size();
int c1=1;
long start = System.currentTimeMillis();
for(int i=0;i<size;i++){
c1 = list.get(i);
}
long end = System.currentTimeMillis()-start;
System.out.println("for + get(i)方法: " + end);


start = System.currentTimeMillis();
for(int c2:list){
}
end = System.currentTimeMillis()-start;
System.out.println("Iterator(foreach)方法:" + end);


int i = 0;
size = list.size();
start = System.currentTimeMillis();
while(i<size){
c1 = list.get(i);
i++;
}
end = System.currentTimeMillis()-start;
System.out.println("While + get(i)方法:" + end);

start = System.currentTimeMillis();
for(Iterator iterator = list.iterator(); iterator.hasNext();) {
c1 = (Integer) iterator.next();
}
end = System.currentTimeMillis()-start;
System.out.println("for iterator方法:" + end);
}

}



ZangXT 2008-09-30
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 xieyaa 的回复:]
也不一定就失去了意义,因为在实际应用中就是这样用的,怎么也做不到在绝对公平的条件下测试。
[/Quote]
2楼也说过了,使用foreach和直接使用Iterator的代码其实是一样的,不过是编译器自动处理的而已。
代码都是一样的,性能差距是怎么来的呢?
xieyaa 2008-09-30
  • 打赏
  • 举报
回复
也不一定就失去了意义,因为在实际应用中就是这样用的,怎么也做不到在绝对公平的条件下测试。
ZangXT 2008-09-29
  • 打赏
  • 举报
回复
每次增加的是Integer.intValue操作,使比较失去了意义。
ZangXT 2008-09-29
  • 打赏
  • 举报
回复
17楼的测试本身是有问题的:
public void forTest(List<Integer> t){
for(int i = 0; i < t.size();i++){
t.get(i);
}
}


public void foreachTest(List<Integer> t){
for(int j : t){

}
}
for测试直接用t.get(i);
foreach测试却
for(int j : t){

}
中间增加了Integer到int的转换过程。
lihan6415151528 2008-09-29
  • 打赏
  • 举报
回复
顶楼上
laiwusheng 2008-09-29
  • 打赏
  • 举报
回复
楼主,我用100000最小数据测试了一下:

import java.util.*;
public class CMPfor
{
final long N = 1000000;
private ArrayList<Integer> aT = new ArrayList<Integer>();

private LinkedList<Integer> LT = new LinkedList<Integer>();

public CMPfor(){
for(int i = 0; i < N; i++){
aT.add(i);
}
for(int i = 0; i < N; i++){
LT.add(i);
}
}

public void forTest(List<Integer> t){
for(int i = 0; i < t.size();i++){
t.get(i);
}
}


public void foreachTest(List<Integer> t){
for(int j : t){

}
}

public void iteratorTest(List<Integer> t){
Iterator it = t.iterator();
while(it.hasNext()){
it.next();
}
}


public void whileTest(List<Integer> t){
int i = 0;
while(i < N){
t.get(i);
i++;
}
}

public static void main(String[] args){

CMPfor cf = new CMPfor();

long a,b;

System.out.println("ArrayList Test:");
a=System.currentTimeMillis();

cf.forTest(cf.aT);

b=System.currentTimeMillis();

System.out.println("forTest: "+(b-a)+"ms");

a=System.currentTimeMillis();

cf.foreachTest(cf.aT);

b=System.currentTimeMillis();

System.out.println("foreachTest: "+(b-a)+"ms");

a=System.currentTimeMillis();

cf.iteratorTest(cf.aT);

b=System.currentTimeMillis();

System.out.println("iteratorTest: "+(b-a)+"ms");


a=System.currentTimeMillis();

cf.whileTest(cf.aT);

b=System.currentTimeMillis();

System.out.println("whileTest: "+(b-a)+"ms");


System.out.println("LinkedList Test:");
a=System.currentTimeMillis();

cf.forTest(cf.LT);

b=System.currentTimeMillis();

System.out.println("forTest: "+(b-a)+"ms");

a=System.currentTimeMillis();

cf.foreachTest(cf.LT);

b=System.currentTimeMillis();

System.out.println("foreachTest: "+(b-a)+"ms");

a=System.currentTimeMillis();

cf.iteratorTest(cf.LT);

b=System.currentTimeMillis();

System.out.println("iteratorTest: "+(b-a)+"ms");


a=System.currentTimeMillis();

cf.whileTest(cf.LT);

b=System.currentTimeMillis();

System.out.println("whileTest: "+(b-a)+"ms");
}
}


结果如下:
ArrayList Test:
forTest: 10ms
foreachTest: 20ms
iteratorTest: 10ms
whileTest: 10ms
LinkedList Test:
forTest: 108135ms
foreachTest: 10ms
iteratorTest: 10ms
whileTest: 120644ms


另一组运行结果:
ArrayList Test:
forTest: 10
foreachTest: 10
iteratorTest: 20
whileTest: 0
LinkedList Test:
forTest: 105852
foreachTest: 10
iteratorTest: 20
whileTest: 104851

事实证明:
不同的集合类型处理的时间不同
LinkedList 不要用for和while
foreach比Iterator快
ArayList中,遍历速度:while>for>foreach
lzheng2001 2008-09-29
  • 打赏
  • 举报
回复
将ArrayList 改成LinkedList,并把集合的元素改少(如果不改少,时间会很长...),可以测试LinkedList的效果.
加载更多回复(15)

62,616

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧