在几个线程上运行Parallel.Foreach的性能

anc*_*dra 5 .net c# parallel-processing performance

我有3个主要的处理线程,每个线程都通过Parallel.Foreach对ConcurrentDictionaries的值执行操作.词典的大小从1,000个元素到250,000个元素不等

TaskFactory factory = new TaskFactory();
Task t1 = factory.StartNew(() =>
{
        Parallel.ForEach(dict1.Values, item => ProcessItem(item));
});

Task t2 = factory.StartNew(() =>
{                                
        Parallel.ForEach(dict2.Values, item => ProcessItem(item));
});

Task t3 = factory.StartNew(() =>
{                           
        Parallel.ForEach(dict3.Values, item => ProcessItem(item));
});
t1.Wait();
t2.Wait();
t3.Wait();
Run Code Online (Sandbox Code Playgroud)

我比较了这个构造的性能(总执行时间)和刚刚在主线程中运行Parallel.Foreach并且性能提高了很多(执行时间减少了大约5倍)

我的问题是:

  1. 上面的方法有问题吗?如果是,那么改进的内容和方式如何?
  2. 执行时间不同的原因是什么?
  3. 调试/分析这种情况的好方法是什么?

编辑:进一步澄清情况:我在WCF服务上模拟客户端调用,每个调用都来自一个单独的线程(任务的原因).我还尝试使用ThreadPool.QueueUserWorkItem而不是Task,没有性能提升.字典中的对象具有20到200个属性(只是小数和字符串),并且没有I/O活动

我通过在BlockingCollection中排队处理请求并在那时处理它们来解决了这个问题

dig*_*All 7

你可能过度并行化了.

如果已经在每个任务中使用了良好(且平衡)的并行化,则无需创建3个任务.

Parallel.Foreach已经尝试使用正确数量的线程来充分利用CPU的全部潜力而不会使其饱和.通过创建其他任务,Parallel.Foreach你可能会让它饱和.
(编辑:正如Henk所说,他们在协调并行运行时产生的线程数可能存在一些问题,至少这会导致更大的开销).

看看这里有一些提示.