Skip to content

Instantly share code, notes, and snippets.

@eksperimental
Created July 3, 2016 17:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eksperimental/d9d98c1f4e47ecbcb19a6affe872dff4 to your computer and use it in GitHub Desktop.
Save eksperimental/d9d98c1f4e47ecbcb19a6affe872dff4 to your computer and use it in GitHub Desktop.
defmodule EnumRandomOriginal do
def random(enumerable) do
case Enum.take_random(enumerable, 1) do
[] -> raise Enum.EmptyError
[e] -> e
end
end
end
defmodule EnumRandomNew do
def random(enumerable) do
case Enum.count(enumerable) do
0 ->
raise Enum.EmptyError
count ->
Enum.at(enumerable, random_integer(0, count - 1))
end
end
defp random_integer(limit, limit) when is_integer(limit),
do: limit
defp random_integer(lower_limit, upper_limit) when is_integer(lower_limit) and is_integer(upper_limit),
do: do_random_integer(lower_limit, upper_limit)
defp do_random_integer(lower_limit, upper_limit) when upper_limit > lower_limit,
do: lower_limit + :rand.uniform(upper_limit - lower_limit + 1) - 1
defp do_random_integer(lower_limit, upper_limit),
do: do_random_integer(upper_limit, lower_limit)
end
defmodule EnumRandomBench do
use Benchfella
@list_empty []
@map_empty %{}
@range 1..1000
@range_big -100_000..100_000
@list Enum.to_list(@range)
@list_big Enum.to_list(@range_big)
@map @list |> Enum.map(fn(v) -> {v, v} end) |> Enum.into(%{})
@map_big @list_big |> Enum.map(fn(v) -> {v, v} end) |> Enum.into(%{})
terms = [ list: @list, list_empty: @list_empty, list_big: @list_big,
map: @map, map_empty: @map_empty, map_big: @map_big,
]
for module <- [EnumRandomOriginal, EnumRandomNew], {term_name, term} <- terms do
@module module
@term_name term_name
@term term
bench "#{@module}: #{@term_name}" do
try do
@module.random @term
rescue
Enum.EmptyError ->
:ok
else
_ ->
:ok
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment