记一次list集合优化
已知某个列表List1有2000条数据,但是因为这个列表的某个字段要从另一个表查询,所以根据一个关联的查询条件查出来的另一个List2有将近75000条数据,然后需要先循环第一个List1,然后循环里面取寻找List2里面符合条件的,因为有某种业务逻辑,所以无法减少List2的sql查询结果数量,所以到最后导出2000条数据需要十几秒,一般而言,计算机循环2000条数据可能不到1秒钟,所以第一个反应是优化List2的循环。
原来的代码如下,开始使用的是通过Linq来筛选条件,数据少的时候还可以,但是当数据多的时候,相当于循环2000*70000次,效率可想而知:
1 2 3 4 5 6 | IList<ProjectSchedulePlanByTaskItem> items = IoCContainer.Get<IProjectSchedulePlanByTaskItemDao>().Select( where ) //将近75000条数据<br> foreach (Task task in taskList) //2000条数据 { data.TaskProgress = GetCurrentStatus(items.Where(linq查询条件)); datas.Add(data); } |
于是我上网百度了一下,得知将字典集合额效率是要比list效率高的,因为Dictionary<TKey,TValue>类实现为哈希表,ContainsKey() 内部是通过Hash查找实现的,查询的时间复杂度是O(1)。貌似Linq的where也是for循环,数量越多,越慢,所以,当我最初只是把Linq改成for循环的时候只是快了一两秒。但是当我把items改成转为Dictionary的时候,从原来的的导出要十几秒减少到只有2~4秒。
1 2 3 4 5 6 7 8 9 10 11 12 13 | Dictionary< int , List<ProjectSchedulePlanByTaskItem>> keyValueByTask= items.GroupBy(s=>s.TaskId).ToDictionary(s => s.Key,s=>s.ToList()); //转为字典集合<br> foreach (Task task in taskList) { TaskProgressData data = new TaskProgressData();<br> IList<ProjectSchedulePlanByTaskItem> whereList = new List<ProjectSchedulePlanByTaskItem>(); if (keyValueByTask.ContainsKey(task.Id)) //查询的时间为O(1),远比list的for循环快 { List<ProjectSchedulePlanByTaskItem> values = keyValueByTask[task.Id]; whereList = values.Where(s => s.ProjectNumber == task.ProjectNumber).ToList(); }<br> data.TaskProgress = GetCurrentStatus(whereList); datas.Add(data); } |
代码很简单,也许很多人都知道,但是很多东西都是从无到有,所以以此记录,加深自己的理解。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库