2011-05-17 64 views
25

较慢下面是代码:Parallel.ForEach比的ForEach

的问题是,Parallel.ForEach大约需要400毫秒VS常规foreach,这需要40ms左右。我究竟做错了什么,为什么不按我的预期工作呢?

+8

基本上,因为涉及到设置成本,并且您没有在循环内做足够的工作来证明开销。见例如[这个答案](http:// stackoverflow。COM /问题/ 2828429 /什么,是最指引换并行的foreach-VS-的foreach/2828486#2828486)。 (我期望这是一个重复的问题。) – Rup 2011-05-17 19:35:38

+2

'Console.WriteLine()'使它完全不相关。 – 2011-05-17 20:36:40

+0

尝试删除'Console.WriteLine()'并将其替换为'c.FirstName = c.FirstName.ToLowerInvariant()'。如果你的收藏品有大约5000件物品,你不会看到差异;但如果您的系列具有6000,7000,10,000项,则在4核处理器上,您将看到很大的差异(“Parallel.Foreach”将会更快) – 2012-05-14 11:43:52

回答

127

假设你有一个任务要执行。假设你是一名数学老师,并且有二十篇论文可以评分。你需要花费你两分钟的时间为一篇论文打分,所以它会花费大约四十分钟。

现在让我们假设你决定要聘请一些助手来帮助你等级的论文。需要一个小时才能找到四名助手。你们每人拿四份报纸,你们都在八分钟内完成。你已经完成了40分钟的工作,共计68分钟的工作时间,包括额外的一小时寻找助手,所以这不是节省。找到助理的开销比自己做这项工作的成本要大。

现在,假设你有两万篇等级,所以它会带你约4分钟。现在,如果你花一个小时找到助手,这是一个胜利。你们每人拿4000份文件,总共花费8060分钟而不是40000分钟,节省了将近5倍。寻找助手的开销基本上是无关紧要的。

并行是不是免费与每个线程完成的工作量相比,在不同线程之间分配工作的成本需要很小。

延伸阅读:

https://en.wikipedia.org/wiki/Amdahl%27s_law

https://en.wikipedia.org/wiki/Gustafson%27s_law

+9

您能否指出一些阅读材料,讨论如何尝试计算完成任务的开销是否可行? – Thelonias 2012-08-17 12:51:56

8

你应该知道的第一件事是,并非所有的并行机制是有益的。并行性存在大量开销,并且这种开销可能会或可能不会很大,取决于并行化的复杂性。由于并行功能的工作量非常小,因此并行性所需的管理开销变得很大,从而减慢了整个工作的速度。

+1

+1 - 比我略快! – Tejs 2011-05-17 19:38:06

8

创建的所有线程的枚举VS只是执行可数的额外开销比有可能的原因放缓了。 Parallel.ForEach不是一个全面的表现增加的举动;无论是否要完成每个元素的操作可能会阻止,都需要权衡。

例如,如果你是做一个网络请求或什么,而不是简单地写到控制台,其水货版本可能会更快。事实上,简单地写入控制台是一个非常快速的操作,因此创建线程并启动它们的开销会变慢。

3

正如前面笔者说,有与Parallel.ForEach相关的一些开销,但不是为什么你不能看到你的性能提升。 Console.WriteLine是一个同步操作,因此一次只能有一个线程正在工作。尝试将身体更改为非阻塞状态,并且您会看到性能提高(只要体内的工作量足够大以超出开销)。