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

时间:2014-09-11 01:39:32

标签: c# .net vb.net asynchronous task-parallel-library

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

在性能方面,将每个操作(HttpWebRequest.GetResponse,Socket.Connect等)改为使用await(GetResponseAsync,ConnectAsync等)的异步方法有什么影响?

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

2 个答案:

答案 0 :(得分:3)

很难量化,但是如果你真的在为网络IO狂欢,你真的需要去异步。运行同步IO,你会让ThreadPool(这是TPL运行任务的地方)挨饿,因为有很多停放的线程在等待他们的响应。

当ThreadPool用完线程时,在决定对压力做出反应之前会有相当长的延迟。它可以真的减慢速度。通过切换到异步IO,您应该注意到性能的显着提高。

作为一般规则,花在ThreadPool线程(阻塞IO)上的时间越少越好。异步将这个时间保持在绝对最小值。

答案 1 :(得分:2)

我对制作或接受有关性能的一般性陈述非常谨慎。这是一个棘手的事情,通常涉及很多依赖。有时并行运行1000件事可能比同步运行1000件更慢,有时候可能要快得多,这实际上取决于1000件任务在做什么,运行任务的硬件,内存等等。等式中有很多变量。

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