gpt4 book ai didi

c# - 如何提高 Parallel.ForEach 的吞吐量

转载 作者:行者123 更新时间:2023-11-30 13:22:39 25 4
gpt4 key购买 nike

我尝试通过并行执行来优化代码,但有时只有一个线程承担所有繁重的负载。下面的例子展示了 40 个任务应该如何在最多 4 个线程中执行,前十个任务比其他的更耗时。

Parallel.ForEach 似乎将数组分成 4 个部分,并让一个线程处理每个部分。所以整个执行大约需要10秒。它应该能够在最多 3.3 秒内完成!

有没有一种方法可以一直使用所有线程,因为在我的实际问题中不知道哪些任务是耗时的?

var array = System.Linq.Enumerable.Range(0, 40).ToArray();

System.Threading.Tasks.Parallel.ForEach(array, new System.Threading.Tasks.ParallelOptions() { MaxDegreeOfParallelism = 4, },
i =>
{
Console.WriteLine("Running index {0,3} : {1}", i, DateTime.Now.ToString("HH:mm:ss.fff"));
System.Threading.Thread.Sleep(i < 10 ? 1000 : 10);
});

最佳答案

使用 Parallel.ForEach 可能,但您需要使用自定义分区器(或找到第 3 方分区器),它能够根据您的需求更明智地对元素进行分区特定项目。 (或者只使用小得多的批处理。)

这也假设您事先并不知道哪些项目会很快,哪些项目会很慢;如果这样做,您可以在调用 ForEach 之前自行重新订购这些元素,这样昂贵的元素就可以分散开来。根据具体情况,这可能足够也可能不够。

一般来说,我更喜欢通过简单地让一个生产者和多个消费者来解决这些问题,每个消费者一次处理一个项目,而不是分批处理。 BlockingCollection 类使这些情况变得相当简单。只需将所有项目添加到集合中,创建 N 个任务/线程/等,每个任务/线程/等等,每个任务都抓取一个项目并处理它,直到没有更多项目为止。它不会为您提供 Parallel.ForEach 为您提供的动态添加/删除线程,但这在您的情况下似乎不是问题。

关于c# - 如何提高 Parallel.ForEach 的吞吐量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20076271/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com