【发布时间】:2016-08-05 09:00:46
【问题描述】:
Java 8
我有一个相当大的集合(大约 1 亿个元素),我需要遍历它并执行一些操作。有两种选择:
遍历一次并完成整个工作(这会使代码变得非常复杂)
迭代两次,在第一次迭代中完成一半的工作,在第二次迭代中休息(这将显着简化代码)
所以,我认为迭代并没有那么昂贵,并写了一个简单的例子来衡量它(我不经常写基准,因此它可能看起来有点傻):
Collection<Double> col = new LinkedList<>();
for(int i = 0; i < 30000000; i++){
col.add(Math.sqrt(i + 1));
}
long start1 = System.nanoTime();
Double res = 0.0;
for(Double d : col){
res += d + d;
}
long end1 = System.nanoTime();
System.out.println(end1 - start1);
System.out.println("=================================");
long start2 = System.nanoTime();
Double res2 = 0.0;
for(Double d : col){
res2 += d;
}
for(Double d : col){
res2 += d;
}
long end2 = System.nanoTime();
System.out.println(end2 - start2);
平均结果如下:
1107881047第一
2133450162 秒(慢两倍)
所以,迭代是一个相当缓慢的过程。但我不明白为什么?我认为我们做的工作量几乎相同,所以性能会有很大不同。
值得注意的是,如果我使用ArrayList而不是链表,结果是:
3858616604第一
422297749 第二个(比第一个快十倍,比上面的例子快两倍)。
您能不能简单地解释一下这种性能差异?
【问题讨论】:
-
您的代码中有很多装箱/拆箱,这肯定会导致您遇到的性能下降。如果可能的话,你应该修改你的代码以避免这种情况。
-
@ray 是的,我知道。但问题不在于这一点。我担心 Array/LinkedList 的性能。
-
“我们做的工作量几乎相同”,第二个测试是做两倍的工作量略少于两倍的时间,所以它更快而不是更慢。你会期望它会更快一点,因为它已经预热了 LinkedList 代码。
标签: java performance list