为什么Elixir的Access行为不是协议?

Mig*_*ter 39 elixir

在最新版本的Elixir中,Access不再作为协议实现,而是作为一种行为实现.从我收集的内容来看,这种变化是出于开发模式中的性能考虑.

现在,看一下实现,我想知道这是如何在内部工作的,以及为什么选择这个实现.正如我们在这里看到的,Access通过底层映射的"__struct__"键调度到struct的模块.AFAICS,这大致类似于OOP风格的多态.关于这个的一些问题:

  1. 为什么这会更快?
  2. 与协议相比有哪些缺点?据我所知,它不太可扩展.还有其他吗?
  3. 到目前为止,我只看到像GenServer这样的东西的行为,其中回调模块在初始化时捕获并保存在一个进程中(至少我假设同样多).这里,Access行为从数据中获取回调模块.是否有可能为不是结构的东西实现这种行为?
  4. 当人们对协议给出的额外好处不感兴趣时​​,这种调度是Erlang还是Elixir的常见最佳实践?

She*_*yar 5

正如您已经提到的那样,Access的实现已更改为使用“行为”而不是“协议”。原因是性能。

  • 协议是基于类型/数据的多态性,并且是Elixir专有的。这意味着您可以根据数据结构进行调度
  • 行为是一种无类型的机制,它不依赖于数据结构,而是依赖于模块作为参数。它们还内置在Erlang / OTP生态系统中,并且性能更高。

虽然协议调度;根据数据类型时做了很多繁重的你的,他们仍然会永远不够快Access,因为他们实现(合并)的方式,

因此,尽管在需要将某些功能绑定到数据结构而不是模块时应始终使用协议,但这Access是一种特殊情况。

由于Access协议依赖于开发和测试模式下的代码服务器(未应用协议合并时),因此,由于代码服务器已成为具有多个进程的瓶颈,因此我们听到了许多有关系统性能严重下降的报告。

发生这种情况是因为该Access协议最终被调用了数千次,并且我们无法做很多改进(与内联大多数列表情况的Enumerable协议相反)。

何塞·瓦利姆


进一步阅读: