c# - Parallel.Invoke 与 Parallel.Foreach 用于在大型列表上运行并行进程

标签 c# multithreading parallel.foreach parallel.invoke

我有一个包含大约 8000 个项目(文件路径)的 C# 列表。我想对所有这些项目并行运行一个方法。为此,我有以下 2 个选项:

1) 手动将列​​表分成小块(比如每个 500 大小)并为这些小列表创建操作数组,然后调用 Parallel.Invoke,如下所示:

    var partitionedLists = MainList.DivideIntoChunks(500);
    List<Action> actions = new List<Action>();
    foreach (var lst in partitionedLists)
    {
      actions.Add(() => CallMethod(lst));
    }
    Parallel.Invoke(actions.ToArray())

2) 第二种选择是像下面那样运行 Parallel.ForEach

Parallel.ForEach(MainList, item => { CallMethod(item) });
  • 最好的选择是什么?
  • Parallel.Foreach 如何划分列表 分成小块?

请建议,在此先感谢。

最佳答案

第一个选项是任务并行化的一种形式,您可以将任务分成一组子任务并并行执行。从您提供的代码中可以明显看出,您负责在创建子任务时选择粒度级别 [ block ]。如果不依赖于适当的启发式方法,所选的粒度可能太大或太低,并且由此产生的性能增益可能并不显着。 Task-parallelism 用于所有输入值的操作执行时间相似的场景。

第二个选项是数据并行化的一种形式,其中输入数据根据可用的硬件线程/核心/处理器的数量被分成更小的 block ,然后每个单独的 block 是隔离处理。在这种情况下,.NET 库会为您选择正确的粒度级别并确保更好的 CPU 利用率。通常,data-parallelism 用于要执行的操作根据输入值的不同所花费的时间的情况。

总而言之,如果您的操作在输入值范围内或多或少是统一的,并且您知道正确的粒度 [ block 大小],请继续第一个选项。但是,如果情况并非如此,或者您不确定上述问题,请选择第二个选项,在大多数情况下通常效果更好。

注意:如果这是您应用程序中对性能非常关键的组件,除了上述建议之外,我还建议您使用这两种方法对类似生产环境中的性能进行基准测试以获得更多数据.

关于c# - Parallel.Invoke 与 Parallel.Foreach 用于在大型列表上运行并行进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47344777/

相关文章:

c# - 企业库错误

c# - 如何设置 Bitmap.Width 和 Bitmap.height

java - SwingWorker 线程可重用性

c++ - 由于新的 const,C++11 对象在多线程环境中可能会变慢吗?

c# - 在 Parallel.ForEach 之外设置断点时的列表计数无效

.net - Parallel.For 多久调用一次 localInit?

c# - 并行聚合集合

c# - 增加 version.props 中的数字

c# - 为什么 NHibernate 不能在每个具体类映射的联合子类表中使用标识?

python - 如何在 Matplotlib 中与线程一起执行动画?