这是代码:
using (var context = new AventureWorksDataContext()) { IEnumerable<Customer> _customerQuery = from c in context.Customers where c.FirstName.StartsWith("A") select c; var watch = new Stopwatch(); watch.Start(); var result = Parallel.ForEach(_customerQuery, c => Console.WriteLine(c.FirstName)); watch.Stop(); Debug.WriteLine(watch.ElapsedMilliseconds); watch = new Stopwatch(); watch.Start(); foreach (var customer in _customerQuery) { Console.WriteLine(customer.FirstName); } watch.Stop(); Debug.WriteLine(watch.ElapsedMilliseconds); }
问题是,Parallel.ForEach大约foreach需要400毫秒,而常规大约需要40毫秒。我到底在做错什么,为什么这不能按我预期的那样工作?
Parallel.ForEach
foreach
假设您有一项任务要执行。假设您是一位数学老师,并且有20篇论文要评分。一篇论文要花两分钟,所以大约要花40分钟。
现在,假设您决定雇用一些助手来帮助您对论文进行评分。找到四个助手需要一个小时。你们每个人要写四篇论文,而且八分钟之内就完成了。您已经将40分钟的工作时间换成了68分钟的工作时间,包括寻找助手的额外时间,所以这不是节省。寻找助手的开销大于自己完成工作的成本。
现在假设您有两万篇论文要评分,因此大约需要40000分钟。现在,如果您花一个小时寻找助手,那就是胜利。你们每个人要拿出4000篇论文,总共需要8060分钟而不是40000分钟,而节省的时间几乎是5倍。寻找助手的开销基本上是无关紧要的。
并行化 不是免费的 。 与每个线程完成的工作量相比,在不同线程之间分配工作的成本应很小。
进一步阅读:
https://zh.wikipedia.org/wiki/Amdahl%27s_law
https://zh.wikipedia.org/wiki/Gustafson%27s_law