两个List循环效率对比 List转Map 循环效率对比 Listmap 循环 效率对比
迪丽瓦拉
2024-04-02 15:52:50
0

        两个List循环效率对比 List转Map 循环效率对比 Listmap 循环 效率对比

一、情景描述

        1、在微服务开发中,如: 查询用户列表 userList,需要关联查询 每个用户下面的文件信息,由于数据库层隔离,不能直接进行 left join ,则需要通过关联查询 文件服务,来获取每个用户下的文件信息,伪代码如下:

List userList = userService.getList(xx);List userFileList = fileService.getList(userIdList);

        2、再通过 关联的id,进行匹配; 一般进行匹配的方式有2种,

  • 同时遍历 userList userFileList ,逐一匹配 ;
  • 其中一个 userList 转换为 userListMap,然后遍历另外一个 userFileList ,再进行匹配

        3、本文将模拟以上2种情况,进行测试对比匹配的效率,用于总结后续的开发中,遇到类似的情况,该如何处理的,经验总结。

二、代码实现

        1、定义一个 普通的内部类,有3个属性:

static class User{private  Integer id ;private String name ;private Integer score ;// ingnore getter /setter construction
}

        2、初始化2个 list , 一个 1w数据,一个10w数据


List list = Lists.newArrayList();
List list10 = Lists.newArrayList();@Before
public void before() throws Exception {int n1 = 10_000;int n2 = 1_00_000;System.out.println("n1 ="+n1 +" ; n2="+n2);initList(n1);initList2(n2);System.out.println("初始化 list 完成 , list = "+ list.size() + " list10 = "+ list10.size());
}private void initList(int n) {for (int i = 0; i < n; i++) {list.add(new User(i,"小明"+i));}
}private void initList2(int n2) {for (int i = 0; i < n2; i++) {list10.add(new User(i,"小明"+i, new Random().nextInt()));}
}

        3、1w List 循环 10w List :

@Test
public void listCompare() throws Exception {final StopWatch stopWatch = StopWatch.createStarted();list.forEach(e->{list10.forEach(e2->{if(e.getId().equals(e2.getId())){e.setScore(e2.getScore());}});});System.out.println("测试匹配情况: list, 100=" + list.get(100).getScore()+ " ; list10 , 100="+list10.get(100).getScore());stopWatch.stop();System.out.println("1w List 循环 10w List,耗时:" + stopWatch.getTime()+" ms");
}

        3.1、输出结果如下:

n1 =10000 ; n2=100000
初始化 list 完成 , list = 10000 list10 = 100000
测试匹配情况: list, 100=1980067001 ; list10 , 100=1980067001
1w List 循环 10w List,耗时:7370 ms

        4、10w List 循环 1w List

@Test
public void list10Compare() throws Exception {final StopWatch stopWatch = StopWatch.createStarted();list10.forEach(e->{list.forEach(e2->{if(e.getId().equals(e2.getId())){e2.setScore(e.getScore());}});});System.out.println("测试匹配情况: list, 100=" + list.get(100).getScore()+ " ; list10 , 100="+list10.get(100).getScore());stopWatch.stop();System.out.println("10w List 循环 1w List,耗时:" + stopWatch.getTime()+" ms");
}

        4.1、输出结果如下:

n1 =10000 ; n2=100000
初始化 list 完成 , list = 10000 list10 = 100000
测试匹配情况: list, 100=-110042713 ; list10 , 100=-110042713
10w List 循环 1w List,耗时:1489 ms

        5、 1w List转Map 循环 10w List 对比:

@Test
public void listMapCompare() throws Exception {final StopWatch stopWatch = StopWatch.createStarted();final Map map = list.stream().collect(Collectors.toMap(k -> k.getId(), v -> v));list10.forEach(e->{final User user = map.get(e.getId());if(Objects.nonNull(user)){user.setScore(e.getScore());}});System.out.println("测试匹配情况: list, 100=" + list.get(100).getScore()+ " ; list10 , 100="+list10.get(100).getScore());stopWatch.stop();System.out.println("1w List转Map 循环 10w List 对比,耗时:" + stopWatch.getTime()+" ms");
}

        5.1、输出结果如下:

n1 =10000 ; n2=100000
初始化 list 完成 , list = 10000 list10 = 100000
测试匹配情况: list, 100=690010328 ; list10 , 100=690010328
1w List转Map 循环 10w List 对比,耗时:49 ms

        6、10w List转Map 循环 1w List 对比:

@Test
public void list10MapCompare() throws Exception {final StopWatch stopWatch = StopWatch.createStarted();final Map map = list10.stream().collect(Collectors.toMap(k -> k.getId(), v -> v));list.forEach(e->{final User user = map.get(e.getId());if(Objects.nonNull(user)){e.setScore(user.getScore());}});System.out.println("测试匹配情况: list, 100=" + list.get(100).getScore()+ " ; list10 , 100="+list10.get(100).getScore());stopWatch.stop();System.out.println("10w List转Map 循环 1w List 对比,耗时:" + stopWatch.getTime()+" ms");
}

        6.1、输出结果如下:

n1 =10000 ; n2=100000
初始化 list 完成 , list = 10000 list10 = 100000
测试匹配情况: list, 100=-623027169 ; list10 , 100=-623027169
10w List转Map 循环 1w List 对比,耗时:56 ms

三、总结

        1、2个list 循环的时候,转成一个为 map,再进行匹配,效率更高。

        2、2个循环同时执行时候: 大循环 套 小循环,效率更高 。【二-3 和 二-4】的执行效率对比;比如:循环 100w次, 10000*100 100*10000 效率会更高。

相关内容