当前位置: 首页 > news >正文

公司来了个新同事,把代码耗时从 26856ms 优化到了 748ms,一顿操作猛如虎!

在两张表中查找相同 ID 的数据时,许多开发者会使用两层for循环嵌套。这种写法效率较低,本文将介绍一种提高查找速度的优化方法。

场景

for循环内嵌套for循环,进行数据匹配和处理。时间复杂度为 O(n*m),在数据量较大时性能会急剧下降。

示例

假设有两份List数据:userListuserMemoList。需要遍历userList,根据每个用户的userId,从userMemoList中查找并取出对应userIdcontent值进行后续处理。

import lombok.Data; import java.util.*; import java.util.stream.Collectors; import org.springframework.util.StringUtils; @Data class User { private Long userId; private String name; } @Data class UserMemo { private Long userId; private String content; } public class NestedLoopOptimization { public static List<User> getUserTestList() { List<User> users = new ArrayList<>(); for (int i = 1; i <= 50000; i++) { User user = new User(); user.setName(UUID.randomUUID().toString()); user.setUserId((long) i); users.add(user); } return users; } public static List<UserMemo> getUserMemoTestList() { List<UserMemo> userMemos = new ArrayList<>(); for (int i = 30000; i >= 1; i--) { UserMemo userMemo = new UserMemo(); userMemo.setContent(UUID.randomUUID().toString()); userMemo.setUserId((long) i); userMemos.add(userMemo); } return userMemos; } // ... 后续代码 }

模拟数据:5 万条user数据,3 万条userMemo数据。

未优化的代码

最直接的实现方式,通过两层for循环进行匹配:

public static void nestedLoop(List<User> userTestList, List<UserMemo> userMemoTestList) { for (User user : userTestList) { Long userId = user.getUserId(); for (UserMemo userMemo : userMemoTestList) { if (userId.equals(userMemo.getUserId())) { String content = userMemo.getContent(); // System.out.println("模拟数据content 业务处理......" + content); // 避免打印影响测试结果 } } } }

耗时:约数万毫秒 (5 万 * 3 万次迭代)。

ps:其实数据量小的话,其实没多大性能差别,不过我们还是需要知道一些技巧点。

break 优化

当每个userIduserMemoList中只有一条数据时,找到匹配项后直接break跳出内循环:

public static void breakOptimizedLoop(List<User> userTestList, List<UserMemo> userMemoTestList) { for (User user : userTestList) { Long userId = user.getUserId(); for (UserMemo userMemo : userMemoTestList) { if (userId.equals(userMemo.getUserId())) { String content = userMemo.getContent(); // System.out.println("模拟数据content 业务处理......" + content); // 避免打印影响测试结果 break; // 找到匹配项后跳出内循环 } } } }

耗时:仍然需要遍历较多次,但比嵌套循环略有改善。

使用 Map 优化

public static void mapOptimizedLoop(List<User> userTestList, List<UserMemo> userMemoTestList) { Map<Long, String> contentMap = userMemoTestList.stream().collect(Collectors.toMap(UserMemo::getUserId, UserMemo::getContent)); for (User user : userTestList) { Long userId = user.getUserId(); String content = contentMap.get(userId); if (StringUtils.hasLength(content)) { // System.out.println("模拟数据content 业务处理......" + content); // 避免打印影响测试结果 } } }

耗时:显著减少,通常在数百毫秒级别。

原理

两层for循环嵌套的时间复杂度为 O(n*m),其中 n 和 m 分别为两个列表的长度。使用Map后,get操作的时间复杂度接近 O(1),整体时间复杂度降为 O(n+m),避免了内循环的重复遍历。

HashMapget方法内部使用了getNode方法来查找键值对。getNode方法利用哈希表结构,快速定位到目标键值对。虽然在极端情况下(所有键的哈希值都相同),getNode的时间复杂度会退化为 O(n),但在实际应用中,哈希冲突的概率很低,HashMapget操作效率通常很高。因此无需过于担心O(n)的最坏情况.

// HashMap.getNode() 方法的部分关键代码 (JDK8) final Node<K,V> getNode(int hash, Object key) { // ... (省略部分代码) if (first.hash == hash && ((k = first.key) == key || (key != null && key.equals(k)))) return first; // 找到节点,直接返回 // ... (省略处理哈希冲突的代码) }

通过以上优化,可以显著提高代码的执行效率。尤其是在处理大量数据时,使用Map优化能够带来巨大的性能提升。避免了不必要的计算,从而提升了代码的性能。

总结

优化方法时间复杂度适用场景性能提升
未优化(嵌套循环)O(n * m)数据量较小时可接受最低,耗时数万毫秒
break优化O(n * m)数据量较小,且userId唯一时适用略有提升,减少内循环次数
Map优化O(n + m)数据量大,且需要高效匹配时适用显著提升,耗时百毫秒级
http://www.jsqmd.com/news/312790/

相关文章:

  • 成都消防检测维保服务如何选?中安锦胜十年经验解析
  • 消费观转变,焕颜丸走俏出圈,盼生派nmn成为亚洲抗衰市场黑马
  • 大学生-AI大环境下软件测试开发就业辅导
  • WordPress建站教程入门:Hostinger主机部署WordPress外贸站详细步骤
  • 安装coremltools指定版本
  • 2026年全国紫锥菊提取物厂家排行榜 实操型选型参考 多行业赋能指南
  • 职业发展规划
  • 解决 “不要乱改我的代码” “你应该复用旧的代码” 等ai coding 问题的框架堂堂开源!
  • 2026年1月GEO优化服务商口碑榜:技术与效果双优之选
  • 从零构建企业级AI应用:Dify平台深度实践指南
  • 静态库和动态库的创建
  • 2026年1月geo公司效果增长实测推荐:企业营销计划提效手册
  • 2026年成都硕士留学中介诚信排名,如何选择可靠服务?
  • 2026年合肥留学机构排名,经验丰富机构全面解析
  • 2026年泉州留学机构十强解读,资质正规的重要性
  • 2026年废旧金属回收厂家参考指南:合规技术与区域服务实力解析
  • Java数据类型拓展
  • 完整教程:深入解剖 Redis Cluster:从 16384 分片原理到故障自动转移的硬核实战
  • 安徽阜阳点对点物流同城零担运输多少钱,服务好不
  • 剖析敦煌原生戈壁户外运动服务公司,选哪家更合适
  • Transformer 入门:一篇对初学者友好的深度解析
  • 广州市英语雅思培训机构推荐,2026权威测评出国雅思辅导机构口碑榜单推荐
  • idea+sprinboot+postgres创建WEB项目
  • 大面额天猫超市卡哪里回收更安心
  • 丽江市英语雅思培训辅导机构推荐-2026权威出国雅思课程中心学校口碑排行榜
  • USACO历年青铜组真题解析 | 2023年1月
  • 2025科技综述:指纹浏览器与国内IP适配的核心技术优化与实践
  • 2025 网安缺口 300 万!转行必看的真实职场全揭秘
  • 运维老哥熬的夜受的气,转网安全给你补回来!
  • 南昌英语雅思培训机构推荐|2026权威测评出国雅思辅导机构口碑榜单