news 2026/7/6 22:10:21

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
公司来了个新同事,把代码耗时从 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)数据量大,且需要高效匹配时适用显著提升,耗时百毫秒级
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/28 22:40:35

AI人工智能如何正确入行(小白程序员必收藏)

到底做什么&#xff0c;才算真正入行AI&#xff1f; 这个话题我在之前的分享中多次提及&#xff0c;今天结合工业界实际场景再系统梳理一遍&#xff1a;在企业中直接落地AI技术的岗位&#xff0c;核心可分为三大类——算法类、工程类、数据类。 当下网络上&#xff0c;无论是…

作者头像 李华
网站建设 2026/7/1 17:24:27

深入浅出 CAS:从 CPU 指令到 Java 17 原子类实战

这篇文章会用 Java 17 的视角&#xff0c;把 CAS 从底层原理到实际落地系统地讲清楚。 目标只有一个&#xff1a;看完这一篇&#xff0c;你对 CAS 的理解不再停留在“有三个参数 V/E/N”这种记忆层面&#xff0c;而是能从 CPU 指令一路推演到 Java 代码&#xff0c;再对框架源…

作者头像 李华
网站建设 2026/6/25 23:39:53

Thinkphp和Laravel基于Web的课程设计选题管理系统

目录ThinkPHP与Laravel框架的课程设计选题管理系统摘要项目开发技术介绍PHP核心代码部分展示系统结论源码获取/同行可拿货,招校园代理ThinkPHP与Laravel框架的课程设计选题管理系统摘要 基于ThinkPHP的选题管理系统 ThinkPHP作为国内流行的PHP框架&#xff0c;适合快速开发中小…

作者头像 李华
网站建设 2026/6/29 3:13:46

【收藏不迷路】大模型学习进阶篇:避开误区,从实战到落地全攻略

随着大模型技术的普及&#xff0c;越来越多程序员和AI小白投身其中&#xff0c;但不少人陷入“学了就忘”“实战卡壳”“落地无门”的困境。相较于基础入门&#xff0c;掌握科学的学习方法、精准避开技术坑点、聚焦场景落地&#xff0c;才是快速吃透大模型的关键。本文基于实战…

作者头像 李华
网站建设 2026/7/6 9:04:43

飞机起落架减震系统

1.2飞机起落架的布置形式 起落架的布置形式是指飞机起落架支柱(支点)的数目和其相对于飞机重心的布置特点。目前&#xff0c;飞机上通常采用四种起落架形式&#xff1a; 图1.1 后三点式起落架 后三点式起落架&#xff1a;这种起落架有一个尾支柱和两个主起落架。并且飞机的重…

作者头像 李华
网站建设 2026/6/28 23:45:55

普通人想入网络安全,到底该走哪条路?

对普通人来说&#xff0c;网络安全这条路到底该怎么走&#xff1f; 由于我之前写了不少网络安全技术相关的故事文章&#xff0c;不少读者朋友知道我是从事网络安全相关的工作&#xff0c;于是经常有人在微信里问我&#xff1a; 我刚入门网络安全&#xff0c;该怎么学&#xff…

作者头像 李华