-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Closed
Description
Currently it is not possible to make use of a receive optimisation[1] without using :erlang.monitor/2
directly. The optimisation doesn't occur when using Process.monitor/1
because the call is not to :erlang.make_ref/1
or :erlang.monitor/2
directly.
Example:
defmodule RecvOpt do
def bench() do
:ok = setup()
{ elixir_time, :ok } = :timer.tc(&elixir_call/0)
{ erlang_time, :ok } = :timer.tc(&erlang_call/0)
{ elixir_time, erlang_time }
end
defp setup() do
_ = Enum.each(1..1000000, fn(_) -> self() <- :hi end)
:ok
end
defp elixir_call() do
pid = Process.spawn(&target/0)
selfie = self()
ref = Process.monitor(pid)
:erlang.send(pid, {:tag, {selfie, ref}, :hi})
receive do
{^ref, :hello} ->
:ok
{:"DOWN", ^ref, _, _, reason} ->
reason
end
end
defp erlang_call() do
pid = Process.spawn(&target/0)
selfie = self()
ref = :erlang.monitor(:process, pid)
:erlang.send(pid, {:tag, {selfie, ref}, :hi})
receive do
{^ref, :hello} ->
:ok
{:"DOWN", ^ref, _, _, reason} ->
reason
end
end
defp target() do
receive do
{:tag, {from, ref}, _} ->
from <- {ref, :hello}
end
end
end
[1] http://erlang.org/pipermail/erlang-questions/2010-June/051751.html