在一大块同步代码上等待大量的小任务是否有性能优势

本文关键字:是否 任务 性能 同步 代码 等待 | 更新日期: 2023-09-27 18:21:31

我有一段代码需要运行大约1000个实例。我正在使用任务并行库启动1k个任务,然后等待它们用Await Task.WhenAll完成。这是一个相当大的纯同步方法集合,涉及许多web请求和套接字连接。

就性能而言,将每个操作(HttpWebRequest.GetResponse、Socket.Connect等)更改为带有等待(GetResponseAsync、ConnectAsync等)的异步方法会产生什么影响?

我想知道它是否能够更好地在多个核心上共享CPU负载,因为每个方法调用都是一个Task,尽管内存开销更大。这是正确的还是我的假设是错误的?

在一大块同步代码上等待大量的小任务是否有性能优势

这很难量化,但如果你真的对网络IO感到困惑,你真的需要异步。运行sync IO时,您会让许多停放的线程等待它们的响应,从而使ThreadPool(TPL运行任务的地方)挨饿。

当ThreadPool的线程用完时,在它决定对压力做出反应之前,会有相当长的延迟。它真的会让事情慢下来。您应该注意到,通过切换到异步IO,性能有了显著的提高

一般来说,在ThreadPool线程中停留的时间越少(在IO上阻塞)越好。Async将此时间保持在绝对最小值。

对于做出或接受关于性能的一般化声明,我会非常谨慎。这是一件棘手的事情,通常涉及到很多依赖关系。有时并行运行1000件事情可能比同步运行相同的1000件慢,有时可能快得多,这实际上取决于这1000个任务在做什么,这些任务运行的硬件、内存等。等式中有很多变量。

不要过度设计预期性能优势的东西,性能是你经常感到惊讶的事情,更重要的是能够检测和测量系统中的性能,然后做出更改并再次测量该性能。很多时候,为了让系统运行,你必须做出的改变可能会令人惊讶。