Anonymous function in Elixir - best to use function captures?

Been reading telementry source code when I stumbled upon this comment block. Does anyone have any references or articles about this?

%% <b>Note:</b> due to how anonymous functions are implemented in the Erlang VM, it is best to use
%% function captures (i.e. `fun mod:fun/4' in Erlang or `&Mod.fun/4' in Elixir) as event handlers
%% to achieve maximum performance. In other words, avoid using literal anonymous functions
%% (`fun(...) -> ... end' or `fn ... -> ... end') or local function captures (`fun handle_event/4'
%% or `&handle_event/4' ) as event handlers.
3 Likes

Well I got the answer from the pull request thread.
Basically, when we attach an event handler, telementry will store the handler function in an ETS table. When an event is match and telementry needs to fire that handler, it fetch from the ETS table, copy the function to the process private heap.
In case of anonymous functions, the author suspects that it has to increment a reference counter for garbage collection purpose, causing the contention. This doesn’t happen with global capture functions.

2 Likes

Yes, the main reason is that &__MODULE__.handler/4 is Erlang constant, while &handler/4 is not (it does some magic to preserve the nature of local vs remote call).