Skip to content

Instantly share code, notes, and snippets.

@lmarlow
Last active May 3, 2017 20:09
Show Gist options
  • Save lmarlow/75b68b5d3200ccb2be119edee4ae0b37 to your computer and use it in GitHub Desktop.
Save lmarlow/75b68b5d3200ccb2be119edee4ae0b37 to your computer and use it in GitHub Desktop.
Elixir Macro vs. Runtime check
defmodule MyMacro do
defmacro def_match(pattern) do
quote do
def macro_pattern_match(unquote(pattern)), do: unquote(Macro.var(:matched, nil))
def macro_pattern_match(_), do: :error
end
end
end
defmodule MacroVRuntimBench do
use Benchfella
require MyMacro
@good_user "some_user"
@matching_value {:mystruct, %{to: %{user: @good_user, server: "localhost"},
from: %{user: "another_user", server: "localhost"},
other: [1,2,3]}}
@non_matching_value {:mystruct, %{to: %{user: "diff_user", server: "localhost"},
from: %{user: "another_user", server: "localhost"},
other: [4,3,2]}}
MyMacro.def_match({:mystruct, %{to: %{user: @good_user = matched}}})
def pattern_match({:mystruct, %{to: %{user: @good_user = matched}}}), do: matched
def pattern_match(_), do: :error
def guard_match({:mystruct, %{to: %{user: user}}}) when user == @good_user, do: user
def guard_match(_), do: :error
def runtime_match({:mystruct, %{to: %{user: user}}}) do
if user == @good_user, do: user, else: :error
end
def runtime_match(_), do: :error
bench "macro match" do
@good_user = macro_pattern_match(@matching_value)
:error = macro_pattern_match(@non_matching_value)
end
bench "non-macro match" do
@good_user = pattern_match(@matching_value)
:error = pattern_match(@non_matching_value)
end
bench "guard match" do
@good_user = guard_match(@matching_value)
:error = guard_match(@non_matching_value)
end
bench "runtime match" do
@good_user = runtime_match(@matching_value)
:error = runtime_match(@non_matching_value)
end
end
######################################
# $ mix bench bench/macro_v_runtime_bench.exs
# Settings:
# duration: 1.0 s
#
# ## MacroVRuntimBench
# [14:08:01] 1/4: guard match
# [14:08:11] 2/4: macro match
# [14:08:22] 3/4: non-macro match
# [14:08:32] 4/4: runtime match
#
# Finished in 42.62 seconds
#
# ## MacroVRuntimBench
# benchmark name iterations average time
# guard match 100000000 0.10 µs/op
# non-macro match 100000000 0.10 µs/op
# runtime match 100000000 0.10 µs/op
# macro match 100000000 0.10 µs/op
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment