Skip to content

Instantly share code, notes, and snippets.

@jmbejar
Last active September 27, 2022 15:23
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jmbejar/3761e0fd2905f7aaa0aedbbfda598624 to your computer and use it in GitHub Desktop.
Save jmbejar/3761e0fd2905f7aaa0aedbbfda598624 to your computer and use it in GitHub Desktop.
Benchmarks for duplicate numbers list generation in Elixir.
defmodule ListDupsPerformance do
def number_dups_list1(numbers) do
Enum.reduce(numbers, [], fn n, acc ->
acc ++ List.duplicate(n, n)
end)
end
def number_dups_list2(numbers) do
Enum.reduce(numbers, [], fn n, acc ->
List.duplicate(n, n) ++ acc
end)
|> Enum.reverse
end
def number_dups_list3(numbers) do
Enum.reduce(numbers, [], fn n, acc ->
Enum.reduce(List.duplicate(n, n), acc, &([ &1 | &2 ]))
end)
|> Enum.reverse
end
def number_dups_list4(numbers) do
Enum.map(numbers, &(List.duplicate(&1, &1)))
|> List.flatten
end
def run_benchmarks do
inputs = %{
"short list with low values" => Enum.to_list(1..1000),
"long list with low values" => List.duplicate(1,100_000),
"short list with high values" => [10_000_000, 20_000_000]
}
Benchee.run %{
"Using ++" =>
fn(list) -> number_dups_list1(list) end,
"Using ++ and reverse" =>
fn(list) -> number_dups_list2(list) end,
"Without ++ ([h | t] and reverse)" =>
fn(list) -> number_dups_list3(list) end,
"map / flatten" =>
fn(list) -> number_dups_list4(list) end,
}, time: 20, warmup: 5, inputs: inputs, memory_time: 2
end
end
# Output
# Elixir 1.7.3 - Erlang/OTP 19
# ##### With input long list with low values #####
# Name ips average deviation median 99th %
# Using ++ and reverse 106.07 9.43 ms ±30.53% 8.85 ms 20.28 ms
# map / flatten 99.49 10.05 ms ±26.41% 9.24 ms 20.91 ms
# Without ++ ([h | t] and reverse) 66.73 14.99 ms ±24.15% 13.96 ms 32.41 ms
# Using ++ 0.0320 31272.04 ms ±0.00% 31272.04 ms 31272.04 ms
# Comparison:
# Using ++ and reverse 106.07
# map / flatten 99.49 - 1.07x slower
# Without ++ ([h | t] and reverse) 66.73 - 1.59x slower
# Using ++ 0.0320 - 3316.93x slower
# Memory usage statistics:
# Name Memory usage
# Using ++ and reverse 5.38 MB
# map / flatten 6.10 MB - 1.13x memory usage
# Without ++ ([h | t] and reverse) 10.30 MB - 1.91x memory usage
# Using ++ 63706.91 MB - 11842.31x memory usage
# **All measurements for memory usage were the same**
# ##### With input short list with high values #####
# Name ips average deviation median 99th %
# Using ++ 0.78 1.28 s ±38.99% 1.18 s 2.81 s
# map / flatten 0.48 2.07 s ±44.18% 1.90 s 4.32 s
# Using ++ and reverse 0.42 2.36 s ±36.20% 2.40 s 4.14 s
# Without ++ ([h | t] and reverse) 0.32 3.14 s ±40.03% 2.49 s 5.22 s
# Comparison:
# Using ++ 0.78
# map / flatten 0.48 - 1.61x slower
# Using ++ and reverse 0.42 - 1.84x slower
# Without ++ ([h | t] and reverse) 0.32 - 2.45x slower
# Memory usage statistics:
# Name Memory usage
# Using ++ 486.44 MB
# map / flatten 915.53 MB - 1.88x memory usage
# Using ++ and reverse 941.76 MB - 1.94x memory usage
# Without ++ ([h | t] and reverse) 1372.86 MB - 2.82x memory usage
# **All measurements for memory usage were the same**
# ##### With input short list with low values #####
# Name ips average deviation median 99th %
# Using ++ and reverse 36.76 27.20 ms ±25.10% 25.78 ms 50.27 ms
# Without ++ ([h | t] and reverse) 30.38 32.92 ms ±13.86% 31.43 ms 51.14 ms
# map / flatten 30.21 33.10 ms ±22.02% 32.02 ms 56.01 ms
# Using ++ 0.43 2313.31 ms ±4.84% 2310.84 ms 2517.74 ms
# Comparison:
# Using ++ and reverse 36.76
# Without ++ ([h | t] and reverse) 30.38 - 1.21x slower
# map / flatten 30.21 - 1.22x slower
# Using ++ 0.43 - 85.04x slower
# Memory usage statistics:
# Name Memory usage
# Using ++ and reverse 19.84 MB
# Without ++ ([h | t] and reverse) 22.07 MB - 1.11x memory usage
# map / flatten 15.30 MB - 0.77x memory usage
# Using ++ 1980.66 MB - 99.84x memory usage
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment