Last active
April 5, 2024 17:40
-
-
Save cr0t/95d0ac8e3ebe186e6b83436c286b14c0 to your computer and use it in GitHub Desktop.
Elixir benchmark of two solution approaches for Luhn task from Exercism.org
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Mix.install([:benchee]) | |
defmodule LuhnChecksum do | |
defguard is_even(x) when rem(x, 2) == 0 | |
def with_reverse(digits) do | |
digits | |
|> Enum.reverse() | |
|> Enum.with_index(1) | |
|> Enum.map(fn | |
{d, idx} when is_even(idx) -> luhn_double(d) | |
{d, _} -> d | |
end) | |
|> Enum.sum() | |
end | |
def with_reduce(digits) when is_even(length(digits)) do | |
digits | |
|> Enum.with_index() | |
|> Enum.reduce(0, fn | |
{d, idx}, acc when is_even(idx) -> acc + luhn_double(d) | |
{d, _}, acc -> acc + d | |
end) | |
end | |
def with_reduce(digits), do: with_reduce([0 | digits]) | |
defp luhn_double(digit) do | |
case 2 * digit do | |
d when d > 9 -> d - 9 | |
d -> d | |
end | |
end | |
end | |
short_num = [1, 0, 9] | |
long_num = [2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4] | |
# ensure that all the functions from above return the same result | |
IO.inspect([ | |
LuhnChecksum.with_reduce(short_num) == LuhnChecksum.with_reverse(short_num), | |
LuhnChecksum.with_reduce(long_num) == LuhnChecksum.with_reverse(long_num), | |
], label: "===> All functions return the same result") | |
Benchee.run( | |
%{ | |
"with_reduce-long" => fn -> LuhnChecksum.with_reduce(long_num) end, | |
"with_reverse-long" => fn -> LuhnChecksum.with_reverse(long_num) end, | |
"with_reduce-short" => fn -> LuhnChecksum.with_reduce(short_num) end, | |
"with_reverse-short" => fn -> LuhnChecksum.with_reverse(short_num) end | |
}, | |
time: 5, | |
memory_time: 5, | |
print: [fast_warning: false] | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
===> All functions return the same result: [true, true] | |
Operating System: macOS | |
CPU Information: Apple M3 Pro | |
Number of Available Cores: 11 | |
Available memory: 18 GB | |
Elixir 1.16.2 | |
Erlang 26.2.2 | |
JIT enabled: true | |
Benchmark suite executing with the following configuration: | |
warmup: 2 s | |
time: 5 s | |
memory time: 5 s | |
reduction time: 0 ns | |
parallel: 1 | |
inputs: none specified | |
Estimated total run time: 48 s | |
Benchmarking with_reduce-long ... | |
Benchmarking with_reduce-short ... | |
Benchmarking with_reverse-long ... | |
Benchmarking with_reverse-short ... | |
Calculating statistics... | |
Formatting results... | |
Name ips average deviation median 99th % | |
with_reverse-short 10.94 M 91.42 ns ±32616.82% 42 ns 125 ns | |
with_reduce-long 9.31 M 107.45 ns ±2594.47% 95.80 ns 133.40 ns | |
with_reduce-short 8.33 M 120.00 ns ±29068.65% 42 ns 167 ns | |
with_reverse-long 5.82 M 171.69 ns ±18079.33% 125 ns 250 ns | |
Comparison: | |
with_reverse-short 10.94 M | |
with_reduce-long 9.31 M - 1.18x slower +16.04 ns | |
with_reduce-short 8.33 M - 1.31x slower +28.59 ns | |
with_reverse-long 5.82 M - 1.88x slower +80.27 ns | |
Memory usage statistics: | |
Name Memory usage | |
with_reverse-short 216 B | |
with_reduce-long 480 B - 2.22x memory usage +264 B | |
with_reduce-short 176 B - 0.81x memory usage -40 B | |
with_reverse-long 864 B - 4.00x memory usage +648 B | |
**All measurements for memory usage were the same** |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment