Skip to content

Instantly share code, notes, and snippets.

@trbngr
Last active May 24, 2019 03:31
Show Gist options
  • Save trbngr/4859a01fe1ef87056f65540289d75ab4 to your computer and use it in GitHub Desktop.
Save trbngr/4859a01fe1ef87056f65540289d75ab4 to your computer and use it in GitHub Desktop.
roman numerals benchmarks
Operating System: macOS
CPU Information: Intel(R) Core(TM) i7-6920HQ CPU @ 2.90GHz
Number of Available Cores: 8
Available memory: 16 GB
Elixir 1.8.1
Erlang 21.2
Benchmark suite executing with the following configuration:
warmup: 2 s
time: 5 s
memory time: 0 ns
parallel: 1
inputs: none specified
Estimated total run time: 21 s
Benchmarking conversion...
Benchmarking function head matching...
Benchmarking function head matching [IO List]...
Name ips average deviation median 99th %
function head matching [IO List] 186.26 5.37 ms ±10.11% 5.25 ms 7.02 ms
function head matching 150.36 6.65 ms ±6.86% 6.54 ms 8.32 ms
conversion 80.01 12.50 ms ±14.63% 12.09 ms 17.73 ms
Comparison:
function head matching [IO List] 186.26
function head matching 150.36 - 1.24x slower +1.28 ms
conversion 80.01 - 2.33x slower +7.13 ms
defmodule Roman do
def numerals(num) when num >= 1000, do: "M#{numerals(num - 1000)}"
def numerals(num) when num >= 900, do: "CM#{numerals(num - 900)}"
def numerals(num) when num >= 500, do: "D#{numerals(num - 500)}"
def numerals(num) when num >= 400, do: "CD#{numerals(num - 400)}"
def numerals(num) when num >= 100, do: "C#{numerals(num - 100)}"
def numerals(num) when num >= 90, do: "XC#{numerals(num - 90)}"
def numerals(num) when num >= 50, do: "L#{numerals(num - 50)}"
def numerals(num) when num >= 40, do: "XL#{numerals(num - 40)}"
def numerals(num) when num >= 10, do: "X#{numerals(num - 10)}"
def numerals(num) when num >= 9, do: "IX#{numerals(num - 9)}"
def numerals(num) when num >= 5, do: "V#{numerals(num - 5)}"
def numerals(num) when num >= 4, do: "IV#{numerals(num - 4)}"
def numerals(num) when num >= 1, do: "I#{numerals(num - 1)}"
def numerals(0), do: ""
def numerals_io(num) do
do_numerals_io(num)
|> Enum.reverse()
|> IO.iodata_to_binary()
end
defp do_numerals_io(num, list \\ [])
defp do_numerals_io(num, list) when num >= 1000, do: do_numerals_io(num - 1000, ["M" | list])
defp do_numerals_io(num, list) when num >= 900, do: do_numerals_io(num - 900, ["CM" | list])
defp do_numerals_io(num, list) when num >= 500, do: do_numerals_io(num - 500, ["D" | list])
defp do_numerals_io(num, list) when num >= 400, do: do_numerals_io(num - 400, ["CD" | list])
defp do_numerals_io(num, list) when num >= 100, do: do_numerals_io(num - 100, ["C" | list])
defp do_numerals_io(num, list) when num >= 90, do: do_numerals_io(num - 90, ["XC" | list])
defp do_numerals_io(num, list) when num >= 50, do: do_numerals_io(num - 50, ["L" | list])
defp do_numerals_io(num, list) when num >= 40, do: do_numerals_io(num - 40, ["XL" | list])
defp do_numerals_io(num, list) when num >= 10, do: do_numerals_io(num - 10, ["X" | list])
defp do_numerals_io(num, list) when num >= 9, do: do_numerals_io(num - 9, ["IX" | list])
defp do_numerals_io(num, list) when num >= 5, do: do_numerals_io(num - 5, ["V" | list])
defp do_numerals_io(num, list) when num >= 4, do: do_numerals_io(num - 4, ["IV" | list])
defp do_numerals_io(num, list) when num >= 1, do: do_numerals_io(num - 1, ["I" | list])
defp do_numerals_io(0, list), do: list
@conversions [
{1000, "M"},
{900, "CM"},
{500, "D"},
{400, "CD"},
{100, "C"},
{90, "XC"},
{50, "L"},
{40, "XL"},
{10, "X"},
{9, "IX"},
{5, "V"},
{4, "IV"},
{1, "I"}
]
def numerals_2(num) do
conversion = Enum.find(@conversions, &(elem(&1, 0) <= num))
if conversion do
{arabic, roman} = conversion
"#{roman}#{numerals(num - arabic)}"
end
end
end
list = Enum.to_list(1..10_000)
Benchee.run(%{
"function head matching" => fn -> Enum.map(list, &Roman.numerals/1) end,
"function head matching [IO List]" => fn -> Enum.map(list, &Roman.numerals_io/1) end,
"conversion" => fn -> Enum.map(list, &Roman.numerals_2/1) end
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment