Skip to content

Inline some Process calls #1808

@fishcakez

Description

@fishcakez

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions