gpt4 book ai didi

c# - 使用 Parallel.foreach 时未获得正确的 http 查询并行度

转载 作者:行者123 更新时间:2023-12-03 02:59:54 25 4
gpt4 key购买 nike

我试图同时执行 2000 个 http 查询。使用此代码(主要由响应服务器组成)进行的测试运行时间约为 15 秒:

    public void testTasks()
{
var urls = new List<string>();
urls.AddRange(createUrls());
var start = DateTime.Now;
ConcurrentQueue<string> contents = new ConcurrentQueue<string>();
Task.WaitAll(urls.Select(url =>
{
var client = new HttpClient { Timeout = TimeSpan.FromSeconds(10) };
return client.GetAsync(url).ContinueWith(response =>
{
try
{
var content = response.Result.Content.ReadAsStringAsync().Result;
contents.Enqueue(content);
}
catch (Exception e)
{
}
});
}).ToArray());
var end = DateTime.Now;
var time = end - start;
Console.WriteLine("Time spent in Tasks : " + time.TotalSeconds);
Console.WriteLine("Queue size : " + contents.Count);
}

现在我使用 Parallel.foreach 执行相同的测试,运行时间为 1 分 18 秒:

    public void testParallelForeach()
{
var urls = new List<string>();
urls.AddRange(createUrls());
var start = DateTime.Now;
ConcurrentQueue<string> contents = new ConcurrentQueue<string>();
Parallel.ForEach(urls, new ParallelOptions() { MaxDegreeOfParallelism = urls.Count }, url =>
{
var client = new HttpClient { Timeout = TimeSpan.FromSeconds(10) };
try
{
string content = client.GetStringAsync(url).Result;
contents.Enqueue(content);
}
catch (Exception e)
{

}
});
var end = DateTime.Now;
var time = end - start;
Console.WriteLine("Time spent in ParallelForeach : " + time.TotalSeconds);
Console.WriteLine("Queue size : " + contents.Count);
}

如您所见,我使用的 MaxDegreeOfParallelism 等于服务器数量。但这似乎还不够。

编辑

所以我的问题是:

-为什么我的性能有这么大的差异?

-我们可以使用parallel.foreach达到相同的性能吗?

最佳答案

我想提供一个与斯科特·张伯伦所提供的稍微不同的角度。使用同步或异步 IO 并不重要。重要的是采用什么有效的 DOP(并行度)来发送 HTTP 请求。

不同的 Web 服务会偏好不同的 DOP,您需要凭经验确定最佳 DOP。

CPU 核心数与最佳 IO DOP 无关。只是确保这一点被理解。

第一个解决方案很糟糕,因为它选择了 DOP = urls.Count。第二个不好,因为它选择 DOP 为 TPL 决定的任何值(它等于MaxDegreeOfParallelism = urls.Count,因为这是一个最大值 em>)。这些值都可能不是最优的。

  1. 使用一种众所周知的技术来实现具有精确 DOP 的并行异步 foreach(例如 http://blogs.msdn.com/b/pfxteam/archive/2012/03/05/10278165.aspx )。
  2. 通过实验确定最佳 DOP。

这是一个非常容易解决的问题。您陷入了使用 TPL 内置工具来解决问题的常见陷阱。 TPL 缺乏适当解决此问题所需的工具。

另请注意,调用 Result 会抵消异步 IO 的优势(这在这里非常有用)。请改用 await

关于c# - 使用 Parallel.foreach 时未获得正确的 http 查询并行度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34751188/

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