我有C#列表,其中包含大约8000个项目(文件路径)。我想并行地对所有这些项运行一个方法。为此,我有以下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) });
请提前谢谢。
答案 0 :(得分:4)
第一个选项是task-parallelism
的一种形式,您可以将任务划分为一组子任务并并行执行。从您提供的代码中可以明显看出,您负责在创建子任务时选择粒度级别[块]。如果不依赖于适当的启发式方法,则所选择的粒度可能太大或太低,并且所得到的性能增益可能不是很大。 Task-parallelism
用于要执行的操作对所有输入值花费相同时间的场景。
第二个选项是data-parallelism
的一种形式,其中输入数据根据可用的硬件线程/核心/处理器的数量分成较小的块,然后单独处理每个单独的块。在这种情况下,.NET库会为您选择正确的粒度级别,并确保更好的CPU利用率。传统上,data-parallelism
用于根据输入值在要执行的操作在时间上变化的情况。
总之,如果您的操作在输入值范围内或多或少均匀,并且您 知道 正确的粒度[块大小],请继续选项。但是,如果情况并非如此,或者您不确定上述问题,请使用第二个选项,在大多数情况下通常会更好地进行调整。
注意:如果这是您应用程序中性能非常关键的组件,除了上述建议之外,我还建议使用这两种获取更多数据的方法对生产环境中的性能进行基准测试