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

时间:2015-11-14 02:47:04

标签: elixir

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

现在,看看实现,我想知道这是如何在内部工作的,以及为什么选择这个实现。我们可以看到here,Access通过底层地图的“__struct__”键调度到结构的模块。 AFAICS,这大致类似于OOP风格的多态。关于这个的一些问题:

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

1 个答案:

答案 0 :(得分:1)

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

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

尽管协议在根据数据类型进行分配时为您带来了很多繁重的工作,但由于实现方式(合并),它们仍将Access never be fast enough取代,

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

  

由于Access协议在开发和测试模式下依赖于代码服务器(未应用协议合并时),因此我们听说由于该代码服务器成为瓶颈,该系统在性能上遭受了极大的困扰。多个过程。

     

之所以会发生这种情况,是因为Access协议最终被调用了数千次,并且我们没有太多改进措施(与内联大多数列表情况的Enumerable协议相反)。 / p>      

Jose Valim


进一步阅读: