我有点困惑。在填充循环的第一个迭代中,当我将initial capacity
用作ArrayList
而不是不使用初始容量时,我看到填充时间有所下降。
根据常识和这个问题:Why start an ArrayList with an initial capacity?
它必须绝对相反。
这不是写得很好的基准测试,我想知道:为什么在第一次迭代时在使用ArrayList
的初始容量时总是会消耗更多的时间和CPU?
这是测试:
public class TestListGen {
public static final int TEST = 100_000_000;
public static void main(String[] args) {
test(false);
}
private static void test(boolean withInitCapacity) {
System.out.println("Init with capacity? " + withInitCapacity);
for (int i = 0; i < 5; i++)
av += fillAndTest(TEST, withInitCapacity ? new ArrayList<Integer>(TEST) : new ArrayList<Integer>());
System.out.println("Average: " + (av / 5));
}
private static long fillAndTest(int capacity, List<Integer> list) {
long time1 = System.nanoTime();
for (int i = 0; i < capacity; i++) list.add(i);
long delta = System.nanoTime() - time1;
System.out.println(delta);
return delta;
}
}
输出:
1)
Init with capacity? false
17571882469
12179868327
18460127904
5894883202
13223941250
Average: 13466140630
2)
Init with capacity? true
37271627087
16341545990
19973801769
4888093008
2442179779
Average: 16183449526
我已经在
JDK 1.7.0.40
,JDK 1.8.0.31
上进行了测试 最佳答案
这是一个Java堆分配工件,导致产生意想不到的结果。调整初始堆分配,通过从混合中删除堆分配时间,您将看到更加一致的结果。另外,您需要确保运行基准测试的进程没有被交换。在我的系统上,当TEST = 100_000_000
出现一个OOM错误,并且不得不将其减少为10_000_000
进行测试。另外,我一个又一个地运行了test(false)
和test(true)
。请注意,在启动时分配堆并在以下结果中添加显式gc如何使各个时间更加一致。重新进行热身对于使测试更加一致也很重要,但是我对此并不在意。
原始测试
Init with capacity? false
1714537208
1259523722
1215986030
1098740959
1029914697
Average: 1263740523
Init with capacity? true
343100302
612709138
355210333
603609642
348401796
Average: 452606242
使用
-Xms500m -Xmx500m
进行测试Init with capacity? false
682827716
738137558
576581143
662777089
555706338
Average: 643205968
Init with capacity? true
368245589
312674836
297705054
392935762
307209139
Average: 335754076
测试
-Xms500m -Xmx500m
之前的System.gc()
+ fillAndTest()
Init with capacity? false
502767979
435508363
420956590
487184801
416041923
Average: 452491931
Init with capacity? true
300744404
298446734
299080656
300084036
298473576
Average: 299365881
关于java - 在第一次迭代中将初始容量用于ArrayList时的一些回归,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29258803/