一丶前言
最近一个朋友在优化代码,和我提到了这个集合初始容量的问题。所以想起来第一次看到这个还是在 阿里《Java开发手册》上 ,今天就来复习一下集合初始容量的作用。
二丶案例 (注意注释中的介绍)
话不多说直接上代码(List 案例):
/**
* 注解@ParameterizedTest: 和@Test类似,但是允许带有参数
* 注解@ValueSource: 表示会依次按照ints中的参数运行多次
* 0默认,16阿里推荐,200W刚好的容量,500w需求值1.5倍容量,9000w需求值45倍容量
* @param initialCapacity 初始容量
*/
@ParameterizedTest
@ValueSource(ints = {0,16,2000000,5000000,90000000})
void testListInitialCapacity(int initialCapacity){
long startTime = System.currentTimeMillis();
List<String> list = new ArrayList<>(initialCapacity);
for (int i = 0; i < 100*10000; i++) {
list.add("我就站在你面前");
list.add("你看我几分像从前");
}
long endTime = System.currentTimeMillis();
long time = endTime - startTime;
System.out.println("list耗时 - 容量"+ initialCapacity +" : "+time);
}
结果:
list耗时 - 容量0 : 33
list耗时 - 容量16 : 24
list耗时 - 容量2000000 : 4
list耗时 - 容量5000000 : 10
list耗时 - 容量90000000 : 118
把list换成map再看看:
@ParameterizedTest
@ValueSource(ints = {0,16,2000000,5000000,90000000})
void testMapInitialCapacity(int initialCapacity){
long startTime = System.currentTimeMillis();
Map<String,String> map = new HashMap<>(initialCapacity);
for (int i = 0; i < 100*10000; i++) {
map.put(Integer.toString(i),"我就站在你面前");
map.put(Integer.toString(i),"你看我几分像从前");
}
long endTime = System.currentTimeMillis();
long time = endTime - startTime;
System.out.println("map耗时 - 容量"+ initialCapacity +" : "+time);
}
结果也差不多:
map耗时 - 容量0 : 676
map耗时 - 容量16 : 374
map耗时 - 容量2000000 : 115
map耗时 - 容量5000000 : 138
map耗时 - 容量90000000 : 292
三丶总结
可以看到在容量刚好的时候,性能是最好的。
容量过大或者过小都会导致耗时增加。
可见初始化容量在处理较大数据的时候,是有较为明显的性能提升的。
阿里推荐的初始容量16即使性能不是最好的,但也比默认的0要好很多.
结尾 - 如果想把案例代码复制过去直接运行,可以加上这个依赖:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
如果觉得对您有哪怕有一点帮助,请点个赞支持一下~