Clojure:流程管道中需要多少异步性?

Clojure: how much asynchronity is necessary in a process pipeline?

在 Clojure 中,您可以构建涉及步骤 (s)、一些昂贵 (S)、同步绑定在一起的多步骤流程 (->) 或异步 ( ~>) 分别通过 compchan。我正在尝试了解避免阻塞和提高性能所需的粒度通道。

我们可以使用通道连接每一步,但这似乎是不必要的开销。

~> s ~> s ~> S ~> s

或者我们可以预先使用单个通道并同步组合其他步骤。这在我看来足以避免阻塞主进程。

~> s -> s -> S -> s

我认为这与:

~> S

人们会喜欢更多频道还是更少频道?为什么?

我认为第二个示例类似于在浏览器中调用网络工作者,因为一旦跨越边界,后端位的连接方式不会对主线程产生太大影响。

您不会通过拆分同步步骤并 运行 它们通过通道同步来获得性能 - 无论您在 运行 这些步骤上有多少线程、工人或机器。相反,由于必要的协调开销,您会降低性能。

单个步骤的成本并不重要。选择重构到通过通道同步的进程中的粒度没有意义。

当计算要求其步骤同步执行时,i。 e.一步需要前一步提供结果,同步执行它们是你能做的最好的事情。

通道在您希望暂停计算直到它可以继续使用一个或多个输入源提供的数据的情况下很有用。这允许将非确定性事件考虑在内,例如在运行时决定更喜欢一个输入源,因为它恰好在另一个输入源之前可用。

作为一种协调实用程序,通道永远不会提高性能。您可以使用通道做的所有事情都可以在没有通道的情况下以更好的性能完成。但它通常很乏味且更容易出错。此外,如果没有像通道这样的设计约束,多个线程的正确同步是极其困难的。这就是为什么在大多数情况下,轻微的开销是一个便宜的代价。