如何将列表的子集添加到另一个列表中的对象的属性-最佳/最快的做法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将列表的子集添加到另一个列表中的对象的属性-最佳/最快的做法相关的知识,希望对你有一定的参考价值。

我试图找到一种基于键属性从列表中选择项的子集并将该子集(列表)分配给另一个列表中项的属性的最快,最高效的方法。性能方面很重要,因为这部分代码将在每个工作日被频繁调用。我用滴答声衡量了性能,以清楚地看到相对差异。

我有两个列表(设置示例);

List<CategorySetting> catList;
List<Customer> custList;

CategorySetting实体具有称为SettingsId的属性。 Customer实体也具有SettingsId属性,实际上这是从CustomersCategorySetting的外键。

我编写的第一段代码是最直接的;

// normal for each: 13275 ticks
foreach (var catItem in catList)

   catItem.Customers = custList.Where(c => c.SettingsId == catItem.SettingsId).ToList();

这大约需要13275个刻度。

然后我想也许使用并行处理会更快一些?所以我写了这段代码;

// parallel for each: 82541 ticks
Parallel.ForEach(catList, catItem =>

   catItem.Customers = custList.Where(c => c.SettingsId == catItem.SettingsId).ToList();
);

这花了更长的时间; 82541滴答声。由于这种方法的并行性,这对我来说毫无意义。它应该使用多个线程来执行此操作,因此理论上应该更快。然后我开始怀疑,如果多个线程尝试同时访问客户列表,将会发生什么情况。这可能会导致锁和队列,从而由于开销而花费更多时间?与写入主列表相同。

我尝试了另一种方法。我为catList(主列表)设置了ConcurrentBag

ConcurrentBag<CategorySettings> csBag = new ConcurrentBag<CategorySettings>(catList);

我将清单列表插入已经由ConcurrentDictionary分组的SettingsId

var dict = custList.GroupBy(c => c.SettingsId).ToDictionary(x => x.Key, y => y.ToList());
ConcurrentDictionary<int?, List<Customer>> concDict = new ConcurrentDictionary<int?, List<Customer>>(dict);

最后的尝试是这样的:

// paralell, bag, concurrent dictionary: 40255
Parallel.ForEach(caBag, ca =>
   
   concDict.TryGetValue(ca.SettingsId, out var selCust);
   ca.Customers = selCust;
);

这将需要40255个滴答声。谁能解释为什么这仍然需要更长的时间?更重要的是,除了“只是” foreach循环外,没有别的方法了吗?感觉就像我在这里丢失了一些东西。

任何想法都将不胜感激!

我试图找到一种基于键属性从列表中选择项的子集并将该子集(列表)分配给另一个列表中项的属性的最快,最高效的方法。 ...

答案

您可以尝试使用ToLookup LINQ方法:

以上是关于如何将列表的子集添加到另一个列表中的对象的属性-最佳/最快的做法的主要内容,如果未能解决你的问题,请参考以下文章

如何将我删除的列表中的项目添加到另一个列表中?

Python如何将列表中的元素添加到另一个字符串列表中

如何将文本框中的字符串添加到另一个窗口中的列表视图

更正SQL“JOIN”以从主列表创建子集 - 一个表中的id字段到另一个表中的id和标题#VB / C#

Java 8如何操作一个列表中的对象并将其收集到另一个列表中? [重复]

如何从带有 where 子句的列表中获取数据到另一个列表?