Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
226 views
in Technique[技术] by (71.8m points)

Why is Elixir's Access behaviour not a protocol?

In recent versions of Elixir, Access is no longer implemented as a protocol, but as a behaviour. From what I gather, this change was motivated by performance considerations in development mode.

Now, looking at the implementation, I wonder how this works internally and why this implementation was chosen. As we can see here, Access dispatches to a struct's module via the underlying map's "__struct__" key. AFAICS, this roughly works like OOP-style polymorphism. A few questions about this:

  1. Why is this faster?
  2. What are the downsides compared to Protocols? From what I can tell it is less extensible. Are there other?
  3. So far I have only seen behaviours in the context of stuff like GenServer, where the callback module is captured at initialization and kept in a process (At least I assume as much). Here, the Access behaviour grabs the callback module from the data. Would it even be possible to implement this behaviour for something that is not a struct?
  4. Is this kind of dispatch a common best practice in Erlang or Elixir when one is not interested in the added benefit that a Protocol would give?
question from:https://stackoverflow.com/questions/33704618/why-is-elixirs-access-behaviour-not-a-protocol

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As you've already mentioned, Access's implementation was changed to use Behaviours instead of Protocols. The reasoning was performance.

  • Protocols are type/data based polymorphism, and are exclusive to Elixir. That means it lets you dispatch based on the data structure
  • Behaviours are a typeless mechanism that don't rely on a data structure, but the module as an argument. They're also built right into the Erlang/OTP ecosystem and are much more performant.

While Protocols do a lot of the heavy lifting for you when dispatching based on data types, they will still never be fast enough for Access because of the way they're implemented (consolidation),

So although you should always use Protocols when you need to tie some functionality to a data structure rather than a Module, Access is a special case.

Because the Access protocol relies on the code server in development and test mode (when protocol consolidation is not applied), we have heard multiple reports of the system suffering greatly in performance as the code server becomes a bottleneck with multiple processes.

This happens because the Access protocol ends up being invoked thousands of times and there isn't much we can do to improve it (in contrast to the Enumerable protocol where most of the list cases are inlined).

~ Jose Valim


Further Reading:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...