记一次list集合优化

 

       已知某个列表List1有2000条数据,但是因为这个列表的某个字段要从另一个表查询,所以根据一个关联的查询条件查出来的另一个List2有将近75000条数据,然后需要先循环第一个List1,然后循环里面取寻找List2里面符合条件的,因为有某种业务逻辑,所以无法减少List2的sql查询结果数量,所以到最后导出2000条数据需要十几秒,一般而言,计算机循环2000条数据可能不到1秒钟,所以第一个反应是优化List2的循环。

      原来的代码如下,开始使用的是通过Linq来筛选条件,数据少的时候还可以,但是当数据多的时候,相当于循环2000*70000次,效率可想而知:

        IList<ProjectSchedulePlanByTaskItem> items = IoCContainer.Get<IProjectSchedulePlanByTaskItemDao>().Select(where)//将近75000条数据
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秒。

        Dictionary<int, List<ProjectSchedulePlanByTaskItem>> keyValueByTask= items.GroupBy(s=>s.TaskId).ToDictionary(s => s.Key,s=>s.ToList());//转为字典集合
foreach (Task task in taskList) { TaskProgressData data = new TaskProgressData();
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(); }
data.TaskProgress = GetCurrentStatus(whereList); datas.Add(data); }

  代码很简单,也许很多人都知道,但是很多东西都是从无到有,所以以此记录,加深自己的理解。

上一篇:uni-app 常用api


下一篇:SQL Server 2000:快速清除日志文件的方法