C# 在大列表上运行并行进程的Parallel.Invoke vs Parallel.Foreach

C# 在大列表上运行并行进程的Parallel.Invoke vs Parallel.Foreach,c#,multithreading,parallel.foreach,parallel.invoke,C#,Multithreading,Parallel.foreach,Parallel.invoke,我有一个C#列表,其中包含大约8000项(文件路径)。我想对所有这些项并行运行一个方法。为此,我有以下两种选择: 1)手动将列表分成小块(比如每个小块大小为500),并为这些小块创建操作数组,然后调用Parallel。如下调用: var partitionedLists = MainList.DivideIntoChunks(500); List<Action> actions = new List<Action>(); foreach (var

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

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

    var partitionedLists = MainList.DivideIntoChunks(500);
    List<Action> actions = new List<Action>();
    foreach (var lst in partitionedLists)
    {
      actions.Add(() => CallMethod(lst));
    }
    Parallel.Invoke(actions.ToArray())
  • 这里最好的选择是什么
  • Foreach如何划分列表 分成小块

请提前提出建议。

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

第二个选项是
数据并行的一种形式
,其中输入数据根据可用硬件线程/内核/处理器的数量划分为更小的块,然后单独处理每个块。在这种情况下,.NET库为您选择合适的粒度级别,并确保更好的CPU利用率。通常情况下,
数据并行性
用于待执行的操作在所用时间方面可能有所不同的场景中,具体取决于输入值

总之,如果您的操作在输入值的范围内或多或少是一致的,并且您知道正确的粒度[块大小],请使用第一个选项。然而,如果情况并非如此,或者如果你对上述问题不确定,那么选择第二个选项,这通常在大多数情况下效果更好


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

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

第二个选项是
数据并行的一种形式
,其中输入数据根据可用硬件线程/内核/处理器的数量划分为更小的块,然后单独处理每个块。在这种情况下,.NET库为您选择合适的粒度级别,并确保更好的CPU利用率。通常情况下,
数据并行性
用于待执行的操作在所用时间方面可能有所不同的场景中,具体取决于输入值

总之,如果您的操作在输入值的范围内或多或少是一致的,并且您知道正确的粒度[块大小],请使用第一个选项。然而,如果情况并非如此,或者如果你对上述问题不确定,那么选择第二个选项,这通常在大多数情况下效果更好


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

您也可以使用
AsParallel
LinQ扩展方法;)您还可以使用
AsParallel
LinQ扩展方法;)
Parallel.ForEach(MainList, item => { CallMethod(item) });