c# - 大型列表上的 plinq 需要花费大量时间

标签 c# c#-4.0 plinq

我有两个内存列表播放和消费者,一个有 1500 万个对象,另一个有大约 300 万个对象。

以下是我正在触发的一些查询..

consumersn=consumers.AsParallel()
                    .Where(w => plays.Any(x => x.consumerid == w.consumerid))
                    .ToList();


List<string> consumerids = plays.AsParallel()
                                .Where(w => w.playyear == group_period.year 
                                         && w.playmonth == group_period.month 
                                         && w.sixteentile == group_period.group)
                                .Select(c => c.consumerid)
                                .ToList();


int groupcount = plays.AsParallel()
                      .Where(w => w.playyear == period.playyear 
                               && w.playmonth == period.playmonth 
                               && w.sixteentile == group 
                               && consumerids.Any(x => x == w.consumerid))
                      .Count();

我使用的是 16 核机器和 32 GB RAM,尽管如此..第一个查询运行了大约 20 小时..

我是不是做错了什么..

真诚感谢所有帮助。

谢谢

最佳答案

第一个 LINQ 查询效率很低,并行化只能帮到你这么多。

解释:当你写consumers.Where(w => plays.Any(x => x.consumerid == w.consumerid)) ,这意味着对于 consumer 中的每个对象,您可能会遍历整个 plays列表以查找受影响的消费者。因此,最多 300 万消费者乘以 1500 万次播放 = 45 万亿次操作。即使在 16 个内核中,每个内核也大约有 2.8 万亿次操作。

因此,这里的第一步是按 consumerId 对所有播放进行分组,并将结果缓存在适当的数据结构中:

var playsByConsumerIds = plays.ToLookup(x => x.consumerid, StringComparer.Ordinal);

然后,您的第一个请求变为:

consumersn = consumers.Where(w => playsByConsumerIds.Contains(w.consumerid)).ToList();

这个查询应该更快,即使没有任何并行化也是如此。

我无法修复以下查询,因为我看不到你在使用 group_period 做什么, 但我建议使用 GroupByToLookup一次创建所有组。

关于c# - 大型列表上的 plinq 需要花费大量时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39952453/

相关文章:

.net - PLINQ 更新失败

c# - Parallel Linq - 返回第一个返回的结果

c# - 如何使用代码 "Conventions"映射忽略属性映射

c# - 设置最大网页宽度

c# - 如何将参数传递给 IN 运算符?

C# 在多种方法中锁定对象

c# - Watin 嵌入到 winform 应用程序中

c# - List<T> Any 还是 Count?

时间:2019-01-17 标签:c#graphicsdrawstring()listviewtoimage

c# - PLINQ 有什么真正的好处吗?