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

news/2024/7/7 21:18:00

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

一、情景描述

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

List<User> userList = userService.getList(xx);

List<UserFile> 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<User> list = Lists.newArrayList();
List<User> 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<Integer, User> 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<Integer, User> 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 效率会更高。


http://lihuaxi.xjx100.cn/news/125948.html

相关文章

Endnote X9文献管理器应用---使用总结

Endnote文献管理器应用---使用总结1. 文献分类和文献管理器Endnote2. Endnote使用&#xff08;1&#xff09;新建本地文献库&#xff08;2&#xff09;创建分组和文献导入&#xff08;3&#xff09;文献插入word文档&#xff08;4&#xff09;文献Style编辑&#xff0c;下载&am…

安装 Windows 7 VM虚拟机

目录&#xff08;1&#xff09;选择系统安装语言&#xff0c;时间与格式&#xff0c;键盘格式&#xff08;2&#xff09;点击【Install now】&#xff08;3&#xff09;选择Windows 10系统的具体版本&#xff08;4&#xff09;同意【Applicable notices license terms】&#x…

盘点多边形战士Polygon有哪些扩容解决方案|Tokenview

加密行业里&#xff0c;以太坊扩容问题的解决方案一直是个巨大的市场。多边形战士Polygon则一直以来致力于解决以太坊的扩容问题。什么是Polygon&#xff1f;Polygon是以太坊的layer2扩容方案&#xff0c;通过提供一种通用框架来创建与以太坊相兼容的扩容解决方案&#xff0c;旗…

[CSP-S 2022] 策略游戏 题解

[CSP-S 2022] 策略游戏 题解题面题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1样例 #2样例输入 #2样例输出 #2提示解析小 Q 的选择小 L 的选择总结代码题面 题目描述 小 L 和小 Q 在玩一个策略游戏。 有一个长度为 nnn 的数组 AAA 和一个长度为 mmm 的数组 BBB&am…

EDAS 流量入口网关最佳实践

作者&#xff1a;澄潭 云原生网关介绍 MSE 云原生网关是阿里云提供的下一代网关解决方案&#xff0c;完全兼容 Kubernetes Ingress 标准 API&#xff0c;将流量网关、微服务网关和安全网关三合一&#xff0c;解决了多层网关架构独立设计、独立运维导致的资源消耗大、性能损耗…

Spring学习第1篇:学习spring必备的概念知识

大家家好&#xff0c;我是一名网络怪咖&#xff0c;北漂五年。相信大家和我一样&#xff0c;都有一个大厂梦&#xff0c;作为一名资深Java选手&#xff0c;深知Spring重要性&#xff0c;现在普遍都使用SpringBoot来开发&#xff0c;面试的时候SpringBoot原理也是经常会问到&…

贷中客群评级的场景实现,来试试这些多维的实操方法

客户价值评估是信贷业务体系的典型场景&#xff0c;无论是针对风险控制&#xff0c;还是侧重策略营销&#xff0c;围绕客户群体的价值分层&#xff0c;始终是数据分析范围内一个重要且必要的话题。从信贷风控的角度来讲&#xff0c;客户价值评估可以贯穿贷前、贷中、贷后整个流…

IO流的字符流+对象流+打印流+内存流+随机访问流(2)

IO流的字符流对象流打印流内存流随机访问流&#xff08;2&#xff09; 一、字符流 1.利用字符输出转换流 向文件写入数据 1.文件存在的情况 2.文件不存在的情况 经验&#xff1a;所有的输出流&#xff0c;当文件不存在时都会创建文件 import java.io.FileOutputStream; imp…