title: why pattern matching performance is not much better than ifelse/cond in elixir?
body: <p>I was told that erlang beam tuned a lot with pattern matching, thus the performance is much better than conditional expression. I did a test in elixir, and run the benchmark testing with benchfella. However, I found the pattern matching performance is almost the same level of performance compared with if/cond. </p>
  
  <pre><code>$ mix bench -d 10
  Settings:
    duration:      10.0 s
    mem stats:     false
    sys mem stats: false
  
  [12:30:08] 1/3: PatternMatchBench.if else performance
  [12:30:28] 2/3: PatternMatchBench.cond performance
  [12:30:47] 3/3: PatternMatchBench.pattern match performance
  Finished in 57.5 seconds
  
  PatternMatchBench.if else performance:            10000   1723.24 µs/op
  PatternMatchBench.cond performance:               10000   1723.36 µs/op
  PatternMatchBench.pattern match performance:      10000   1726.95 µs/op
  </code></pre>
  
  <p>Below is the core code, it basically format the data to string under different situation. The whole project could be obtained via <a href="https://github.com/tyrchen/pattern_match" rel="nofollow">https://github.com/tyrchen/pattern_match</a>.</p>
  
  <pre><code>defmodule Ifelse do
    def process(data) do
      if is_list(data) do
        data
        |&gt; Enum.map(fn(entry) -&gt;
            if is_tuple(entry) do
              {k,v} = entry
              "#{k}: #{v}" |&gt; transform
            else
              entry |&gt; process
            end
        end)
        |&gt; Enum.join("\n")
      else
        if is_map(data) do
          data
          |&gt; Enum.map(fn({k, v}) -&gt; transform("#{k}: #{v}") end)
          |&gt; Enum.join("\n")
        else
          data |&gt; transform
        end
      end
    end
  
    defp transform(str) do
      "    #{str}"
    end
  end
  
  defmodule Cond do
    def process(data) do
      cond do
        is_list(data) -&gt;
          data
          |&gt; Enum.map(fn(item) -&gt;
            cond do
              is_tuple(item) -&gt;
                {k, v} = item
                "#{k}: #{v}" |&gt; transform
              true -&gt;
                item |&gt; process
            end
          end)
          |&gt; Enum.join("\n")
        is_map(data) -&gt;
          data
          |&gt; Enum.map(fn({k, v}) -&gt; "#{k}: #{v}" |&gt; transform end)
          |&gt; Enum.join("\n")
        true -&gt;
          "    #{data}"
      end
    end
  
    defp transform(str) do
      "    #{str}"
    end
  
  end
  
  defmodule Pattern do
    def process(data) when is_tuple(data) do
      {k, v} = data
      "#{k}: #{v}" |&gt; process
    end
  
    def process(data) when is_list(data) or is_map(data) do
      data
      |&gt; Enum.map(fn(entry) -&gt; process(entry) end)
      |&gt; Enum.join("\n")
    end
  
    def process(data) do
      "    #{data}"
    end
  
  end
  </code></pre>
  
  <p>Did I miss anything? Or do I need more complicated tests to find out the strength of the pattern matching of erlang VM?</p>