问题描述
在本机测试用例中,初始化键值对100W,初始化容量200W(其实当键值对更少,比如10W,5W等级别,情况也是类似的),发现初始化容量的效率和不初始化容量的效率并不是稳定不变的,为何一直听说当可预估map内容大小时,应该预填容量值呢?
测试代码
int puts = 1000000, cap = puts * 2;
for (int k = 0; k < 5; k++) {
System.out.println("=========独立测试开始==========");
HashMap<Integer, Integer> map5 = new HashMap<Integer, Integer>(cap);
long time01Start = System.currentTimeMillis();
for (int i = 0; i < puts; i++) {
map5.put(i, i);
}
System.out.println("HashMap初始化容量" + puts / 10000 + "W的耗时:" + (System.currentTimeMillis() - time01Start) + "ms");
HashMap<Integer, Integer> map6 = new HashMap<Integer, Integer>();
long time02Start = System.currentTimeMillis();
for (int i = 0; i < puts; i++) {
map6.put(i, i);
}
System.out.println("HashMap未初始化容量" + puts / 10000 + "W的耗时:" + (System.currentTimeMillis() - time02Start) + "ms");
System.out.println("=========独立测试结束==========");
}
5次的测试结果
=========独立测试开始==========
HashMap初始化容量100W的耗时:964ms
HashMap未初始化容量100W的耗时:603ms
=========独立测试结束==========
=========独立测试开始==========
HashMap初始化容量100W的耗时:119ms
HashMap未初始化容量100W的耗时:658ms
=========独立测试结束==========
=========独立测试开始==========
HashMap初始化容量100W的耗时:26ms
HashMap未初始化容量100W的耗时:72ms
=========独立测试结束==========
=========独立测试开始==========
HashMap初始化容量100W的耗时:154ms
HashMap未初始化容量100W的耗时:34ms
=========独立测试结束==========
=========独立测试开始==========
HashMap初始化容量100W的耗时:134ms
HashMap未初始化容量100W的耗时:34ms
=========独立测试结束==========
测试方法不太科学。
最好分开独立测试,放在循环里也不是不行,只是有时候结果不太准确,每次循环之间可能会有影响
考虑JVM内存大小对结果可能产生的影响
应该测试两种情况:预分配容量和不预分配容量的先后顺序可能会对结果有影响,哪个先哪个后应该各占测试次数的一半(
个人感觉题主的结果应该主要是受到了这一条的影响
)测试数据应该再随机一点,而不是用一个循环然后不断
i++
。最好能够使用随机字符串或其他对象进行测试(为避免创建对象的影响,可以预先生成所有数据)考虑
loadFactor
的设置