list.addAll 和Collections.addAll 以及遍历添加方法性能实测对比
项目需求描述:
根据文件夹路径获取其下全部文件列表集合,这些文件是一个完整视频的分块,如下图所示,实际上返回时需要根据文件名(String类型的数字)有序排列才能保证正确性,方法代码如下:
/**
* 获取分块文件列表并排序
* @param chunkfileFolder 分块文件目录
* @return 分块文件列表
*/
private List<File> getChunkFiles(File chunkfileFolder) {
File[] files = chunkfileFolder.listFiles();
if (files == null || files.length == 0) {
logger.error("未查询到分片文件列表,chunkfileFolder:{}", chunkfileFolder);
ExceptionCast.cast(MediaCode.UPLOAD_FILE_REGISTER_ISNULL);
}
List<File> fileList = new ArrayList<>(files.length);
fileList.addAll(Arrays.asList(files));
//Collections.addAll(fileList, files); 效率更低,详见测试类
Collections.sort(fileList, (o1, o2) -> {
return Integer.parseInt(o1.getName()) > Integer.parseInt(o2.getName()) ? 1 : -1;
});
return fileList;
}
问题描述:
1.在代码13和14行时不确定性能于是写了个小Demo,具体如下:
@Test
public void testCollections() {
// 模拟测试数据
Integer[] arr = new Integer[1000000];
for (int i = 0; i < 1000000; i++) {
arr[i] = i;
}
//方式一:listAddAll方法
List<Integer> list1 = new ArrayList<>(1000000);
long start1 = System.currentTimeMillis();
List<Integer> asList1 = Arrays.asList(arr);
list1.addAll(asList1);
System.out.println("ListAddAll 花费时间ms:" + (System.currentTimeMillis() - start1));
//方式二:Collections.AddAll直接添加数组
List<Integer> list2 = new ArrayList<>(1000000);
long start2 = System.currentTimeMillis();
Collections.addAll(list2, arr);
System.out.println("CollectionsAddAll add数组花费时间ms:" + (System.currentTimeMillis() - start2));
//方式三:遍历添加
List<Integer> list3 = new ArrayList<>(1000000);
List<Integer> asList = Arrays.asList(arr);
long start3 = System.currentTimeMillis();
asList.stream().forEach(e -> Collections.addAll(list3, e));
System.out.println("CollectionsAddAll 遍历add集合花费时间ms" + (System.currentTimeMillis() - start3));
// 随机从集合中取出一个元素校验添加是否成功
System.out.println("list1获取索引为10的元素:"+list1.get(10));
System.out.println("list2获取索引为10的元素:"+list2.get(10));
System.out.println("list3获取索引为10的元素:"+list3.get(10));
}
分别测试数据为百万级,十万级,千级数据,最终打印结果如下:
总结:
1、百万级及以上数据,list.addAll() 方法 效率是比Collections.addAll()快很多,遍历方式效率最低;
2、百万级到万级间数据,list.addAll() 方法 效率和Collections.addAll()差不多,遍历效率最低;
3、千级及以下数据,三种方式效率差别不大;
4、Collections.addAll() 方法的优点是无需进行数组向集合的转换,可以将数组直接添加到目标集合中,适合十万级左右数据 ;
5.list.addAll() 方法在百万级以上数据时效率最高;