【问题标题】:Why is async programming faster为什么异步编程更快
【发布时间】:2015-07-10 23:51:47
【问题描述】:

我一直听说使用异步编程模式会使我的代码运行得更快。为什么这是真的?无论是现在运行还是以后运行,相同的确切代码是否必须以任何一种方式运行?

【问题讨论】:

    标签: asynchronous language-agnostic


    【解决方案1】:

    不是更快,只是不浪费时间。

    同步代码在等待 I/O 时停止处理。这意味着当您读取文件时,您无法运行任何其他代码。现在,如果在读取该文件时您无事可做,那么异步代码不会给您带来太多好处。

    通常,您可以使用的额外 CPU 时间对服务器很有用。那么问题来了,为什么要异步编程而不是为每个客户端启动一个新线程呢?

    事实证明,启动和拆除线程的成本很高。早在 2000 年代初期,一个 Web 服务器基准测试发现 tclhttpd 在提供静态图像文件方面优于 Apache。尽管 tclhttpd 是用 tcl 编写的,而 Apache 是用 C 编写的,而且已知 tcl 比 C 慢 50 倍。Tcl 设法与 Apache 抗衡,因为 tcl 有一个易于使用的异步 I/O API。于是 tclhttpd 就使用了。

    并不是说 C 没有异步 I/O API。只是它们很少使用。所以 Apache 没有使用它。如今,Apache2 在内部使用异步 I/O 以及线程池。 C 代码最终看起来更复杂,但速度更快 - 经验教训。

    这导致我们最近对异步编程的痴迷。人们为什么对它着迷? (例如,有关 javascript 编程的 Stackoverflow 上的大多数答案都坚持认为您永远不应该使用异步函数的同步版本)。

    这可以追溯到您很少看到 C 中的异步程序,尽管它是一种出色的做事方式(GUI 代码是一个例外,因为 UI 库很早就学会了依赖异步编程和事件)。 C 中有太多同步的函数。因此,即使您想做异步编程,迟早会调用同步函数。另一种方法是放弃 stdlib 并为所有内容编写自己的异步库 - 从文件 I/O 到网络再到 SQL。

    因此,在像 javascript 这样的语言中,异步编程最终成为默认样式,其他程序员有压力不要把它搞砸并意外引入同步函数,这些函数很难与异步代码集成而不会损失很多性能。所以最终,异步代码就像税收一样成为了一种社会契约。

    【讨论】:

      【解决方案2】:

      它并不总是更快。事实上,仅仅设置和拆除异步环境就会为您的代码增加大量时间。你必须分拆一个新的进程/线程,设置一个事件队列/消息泵,最后很好地清理一切。 (即使您的框架对您隐藏了所有这些细节,它们也会在后台发生)。

      优点是阻塞。我们的很多代码都依赖于外部资源。我们需要查询数据库以获取要处理的记录,或者从网站下载最新版本的内容。从您向该资源询问信息直到您得到答案的那一刻起,您的代码无事可做。正在阻塞,等待答复。您的程序花费在阻塞上的所有时间都完全浪费了

      这就是异步的设计目的。通过将“等待此阻塞操作”代码转为异步请求,您可以让其余的非阻塞代码继续运行。

      作为一个比喻,想象一位经理告诉他的员工那天该做什么。其中一项任务是给等待时间很长的公司打电话。如果他告诉她同步拨打电话,她会拨打电话并等待而不做任何其他事情。让它异步,她可以在手机处于后台保持状态时处理许多其他任务。

      【讨论】:

      • 我喜欢“等待”的比喻
      • 这错过了重点。对于涉及 IO 操作的单个序列来说,它并不快,但它比使用多线程的同步代码更具可扩展性。 Stephen Cleary 解释了这一点 - stackoverflow.com/a/31192718
      【解决方案3】:

      它运行相同的代码,但它不等待耗时任务完成。它将继续执行代码,直到异步功能完成。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-10
        • 2019-05-28
        • 2010-12-18
        • 1970-01-01
        • 2012-06-13
        • 1970-01-01
        • 2021-11-12
        • 2017-03-20
        相关资源
        最近更新 更多