简介:我从System.Threading.Tasks.Parallel.ForEach和Concurrent Data结构更改为简单的p
linq(Parallel
Linq)查询.加速是惊人的.
那么plinq固有地比Parallel.ForEach更快吗?或者它是否特定于任务.
// Original Code // concurrent dictionary to store results var resultDict = new ConcurrentDictionary<string,MyResultType>(); Parallel.ForEach(items,item => { resultDict.TryAdd(item.Name,PerformWork(source)); }); // new code var results = items .AsParallel() .Select(item => new { item.Name,queryResult = PerformWork(item) }) .ToDictionary(kv => kv.SourceName,kv => kv.queryResult);
笔记:
每个任务(PerformWork)现在运行0到200毫秒.在我优化它之前,它需要更长的时间.这就是我在第一个地方使用Tasks.Parallel库的原因.所以我从总时间的2秒到约100-200毫秒的总时间,执行大致相同的工作,只是使用不同的方法. (哇linq和plinq真棒!)
问题:
>由于使用plinq vs Parallel.ForEach,速度是否提高?
>它只是简单地删除并发数据结构(ConcurrentDictionary)? (因为它不需要同步线程).
>基于此related question的答案
Whereas PLINQ is largely based on a functional style of programming with no side-effects,side-effects are precisely what the TPL is for. If you want to actually do work in parallel as opposed to just searching/selecting things in parallel,you use the TPL.
我可以假设,因为我的模式基本上是功能性的(给输入产生没有变异的新输出),plinq是正确使用的技术吗?
我正在寻找验证我的假设是正确的,或者表明我错过了什么.
解决方法
根据您在样本中提供的有限信息(我在OP的评论中询问了更多详细信息),我猜测您会发现由于使用的分区算法而产生的差异.您应该在这篇博客文章中阅读
Chunk Partitioning vs. Range Partitioning,其中讨论了它们的不同之处以及它们可能最适合的工作类型.强烈建议您阅读该博客文章以及
this one,其中详细介绍了这两种类型以及可以使用的其他两种类型的分区,但不适用于您的样本,以及提供一些视觉帮助以更好地了解分区.最后,here’s yet another blog post讨论了工作分区以及当默认分区算法对您的特定工作负载没有意义时它如何影响您.该帖实际上是指一个很棒的程序,可以帮助您在
a set of parallel samples from the PFX team的工作中可视化分区程序.