Parallel.Invoke vs Parallel.Foreach 对于 运行 大型列表的并行处理

Parallel.Invoke vs Parallel.Foreach for running parallel process on large list

我有一个包含大约 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) });

求推荐,先谢谢了

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

第二个选项是data-parallelism的一种形式,其中输入数据根据可用硬件threads/cores/processors的数量分成更小的块,然后单独处理每个单独的块.在这种情况下,.NET 库会为您选择合适的粒度级别并确保更好的 CPU 利用率。通常,data-parallelism 用于要执行的操作在所用时间方面可能因输入值而异的情况。

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

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