验证Collectors.groupingByConcurrent和 Collectors.groupingBy效率问题 (并行流 串行流)
程序员文章站
2022-04-15 23:41:47
一、定义实体类(数据载体) @Data public static class Stu { private Integer userId; private String fromClassId; }二、定义main方法 public static void main(String[] args) { List studentDTOS = Lists.newArrayList(); ....
一、定义实体类(数据载体)
@Data
public static class Stu {
private Integer userId;
private String fromClassId;
}
二、定义main方法
public static void main(String[] args) {
List<Stu> studentDTOS = Lists.newArrayList();
for (int i = 0; i < 20000; i++) {
Stu studentDTO = new Stu();
studentDTO.setUserId(new Random().nextInt(20000) + 10);
studentDTO.setFromClassId(String.valueOf(new Random().nextInt(2) + 10));
studentDTOS.add(studentDTO);
}
long l = System.currentTimeMillis();
Map<Integer, List<Stu>> map = studentDTOS.stream().collect(Collectors.groupingBy(Stu::getUserId));
System.out.println(System.currentTimeMillis() - l);
l = System.currentTimeMillis();
ConcurrentMap<Integer, List<Stu>> map2 = studentDTOS.parallelStream().collect(Collectors.groupingByConcurrent(Stu::getUserId));
System.out.println(System.currentTimeMillis() - l);
boolean result = mapCompar(studentDTOS, map, map2);
System.out.println();
System.out.println(result);
}
private static boolean mapCompar(List<Stu> studentDTOS, Map<Integer, List<Stu>> hashMap, Map<Integer, List<Stu>> hashMap2) {
boolean isChange = false;
for (Map.Entry<Integer, List<Stu>> entry1 : hashMap.entrySet()) {
List<Stu> m1value = entry1.getValue();
if (hashMap2.get(entry1.getKey()) == null) {
break;
}
List<Stu> m2value = hashMap2.get(entry1.getKey());
if (!CollectionUtils.isEqualCollection(m1value, m2value)) {
List<Stu> stus = studentDTOS.stream().filter(stu -> Objects.equal(entry1.getKey(), stu.getUserId())).collect(Collectors.toList());
System.out.println("key:" + entry1.getKey());
System.out.println("1:" + CollectionUtils.isEqualCollection(stus, m1value));
System.out.println("2:" + CollectionUtils.isEqualCollection(stus, m2value));
System.out.println();
System.out.println("样板数据:");
stus.forEach(s -> System.out.print(s.fromClassId + ","));
System.out.println();
System.out.println("m1数据:");
m1value.forEach(m1 -> System.out.print(m1.fromClassId + ","));
System.out.println();
System.out.println("m2数据:");
m2value.forEach(m2 -> System.out.print(m2.fromClassId + ","));
break;
}
isChange = true;
}
return isChange;
}
代码我就不讲解实现思路了,有点基础的应该都可以看懂。
主要就是通过验证(假设有个N条数据,将其分为M个组。然后比较两种分组效率,并且验证两种分组的数据安全性问题)
三、上结论(图片中为两种方式耗时,单位:毫秒;前为串行流,后为并行流)
1.共200000000条数据 分为200000000个组
耗时比较:WC,半天没跑出来,建议不用再内存中分特大量数据。不建议使用
2.共2000000条数据 分为2000000个组
3. 共2000000条数据 分为200个组
4. 共200000条数据 分为200000个组
5. 共200000条数据 分为20个组
6. 共200条数据 分为200个组
7. 共200条数据 分为20个组
8. 共20条数据 分为2个组
代码应该可以运行,有兴趣的同学可以试试自己跑一下,自己动手,可能更能理解。
本文地址:https://blog.csdn.net/qq_40223688/article/details/107354242