ILookUp的使用场景
一、背景
经监控,标签关系上报20w+的标签关系处理耗时达到3800多秒。约一个小时
二、问题定位
- 经排查定位到以下代码耗时占比最大
- 这段代码没有涉及到任务数据库及外部调用
- 其中的_dataCount总共20w+,证明两个foreach一共循环了20w+次
三、复杂度分析
1 外层Foreach循环复杂度分析
-
Foreach循环20w+次可知 循环的复杂度O(N)≈20w
2 内层GetDTO方法复杂度分析
- 由于里面的GetDTO涉及了4个FirstOrDefault(),最大的为tagRelationsModels,其数据量也为20w+
- FirstOrDefault()源码可知其内部也是根据foreach去查找,因此GetDTO方法的复杂度O(M)约等于20w
- FirstOrDefault源码如下
3 总体复杂度分析
- 总体的复杂度为O(N*M)≈400亿+的计算量
四、优化
1 降低总体复杂度
- 由于外层Foreach的复杂度无法降低,因此主要优化内层GetDTO中的复杂度
- 根据ILookUp源码可知其复杂度为O(log2M),20w+的数量在O(log2M)下≈18
- 在尽量不改到原逻辑的情况下,将FirstOrDefault改为ILookUp
- ILookUp源码如下
五、总结&数据对比
- 优化后总体的复杂度为O(N*log2M)≈360w的计算量
- 总计算量由400亿降至360万
- 由于此次优化额外引入了ILookUp,会临时占用一部分内存,所以也涉及到了空间换时间的问题
数据量
|
优化前
|
优化后
|
---|---|---|
93000 | 1235秒 | 122秒 |
68000 | 368秒 | 96秒 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构