gpt4 book ai didi

c# - 异步/等待性能

转载 作者:太空狗 更新时间:2023-10-29 20:58:10 24 4
gpt4 key购买 nike

我正在对广泛使用异步/等待功能的程序进行性能优化。一般来说,它通过 HTTP 并行下载数千个 json 文档,解析它们并使用这些数据构建一些响应。我们遇到了一些性能问题,当我们同时处理许多请求时(例如下载 1000 个 json),我们可以看到一个简单的 HTTP 请求可能需要几分钟。

我编写了一个小型控制台应用程序以在一个简化示例上对其进行测试:

class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 100000; i++)
{
Task.Run(IoBoundWork);
}

Console.ReadKey();
}

private static async Task IoBoundWork()
{
var sw = Stopwatch.StartNew();

await Task.Delay(1000);

Console.WriteLine(sw.Elapsed);
}
}

我可以在这里看到类似的行为:

enter image description here

问题是为什么“await Task.Delay(1000)”最终需要 23 秒。

最佳答案

Task.Delay 没有损坏,但您正在执行 100,000 个任务,每个任务都需要一些时间。在这种特殊情况下,是对 Console.WriteLine 的调用导致了问题。每次调用都很便宜,但它们访问的是共享资源,因此它们的并行化程度不是很高。

如果您删除对 Console.WriteLine 的调用,所有任务都会很快完成。我更改了您的代码以返回每个任务观察到的耗时,然后在最后只打印一行输出 - 最大观察时间。在我的计算机上,没有任何 Console.WriteLine 调用,我看到大约 1.16 秒的输出,显示出非常低的效率:

using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

class Program
{
static void Main(string[] args)
{
ThreadPool.SetMinThreads(50000, 50000);
var tasks = Enumerable.Repeat(0, 100000)
.Select(_ => Task.Run(IoBoundWork))
.ToArray();
Task.WaitAll(tasks);
var maxTime = tasks.Max(t => t.Result);
Console.WriteLine($"Max: {maxTime}");
}

private static async Task<double> IoBoundWork()
{
var sw = Stopwatch.StartNew();
await Task.Delay(1000);
return sw.Elapsed.TotalSeconds;
}
}

然后你可以修改IoBoundWork来做不同的任务,看看效果。尝试的工作示例:

  • CPU 工作(积极地为 CPU 做一些“困难”的事情,但时间很短)
  • 同步休眠(所以线程被阻塞,但 CPU 没有)
  • 没有任何共享瓶颈的同步 IO(尽管这通常很难,因为磁盘或网络很可能最终成为共享资源瓶颈,即使您正在写入不同的文件等)
  • 具有共享瓶颈的同步 IO,例如 Console.WriteLine
  • 异步 IO(await foo.WriteAsync(...) 等)

您也可以尝试删除对 Task.Delay(1000) 的调用或更改它。我发现通过完全删除它,结果非常小 - 而用 Task.Yield 替换它与 Task.Delay 非常相似。值得记住的是,只要您的异步方法必须真正“暂停”,您实际上就在使任务调度问题加倍 - 而不是调度 100,000 个操作,而是调度 200,000 个操作。

您会在每种情况下看到不同的模式。从根本上说,您要启动 100,000 个任务,要求它们全部等待一秒钟,然后要求它们全部做某事。这会导致特定于异步/等待的连续调度方面的问题,还会导致“执行 100,000 个任务,每个任务都需要写入控制台将需要一段时间”的简单资源管理。

关于c# - 异步/等待性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47495824/

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