Skip to content

Instantly share code, notes, and snippets.

@weapp
Last active February 27, 2017 15:44
Show Gist options
  • Save weapp/e5bec3084e5e34047de3a6c080caba0c to your computer and use it in GitHub Desktop.
Save weapp/e5bec3084e5e34047de3a6c080caba0c to your computer and use it in GitHub Desktop.
defmodule MyMap do
def bodyrecursive([]) do [] end
def bodyrecursive([h|t]) do [h + 1 | bodyrecursive(t)] end
def generic_bodyrecursive([], _) do [] end
def generic_bodyrecursive([h|t], fun) do [fun.(h) | bodyrecursive(t)] end
def tail(list) do tail(list, []) end
defp tail([], acc) do :lists.reverse(acc) end
defp tail([h|t], acc) do tail(t, [h + 1 | acc]) end
def generic_tail(list, fun) do generic_tail(list, fun, []) end
defp generic_tail([], _, acc) do :lists.reverse(acc) end
defp generic_tail([h|t], fun, acc) do generic_tail(t, fun, [fun.(h) | acc]) end
def map_tco(list, function) do Enum.reverse _map_tco([], list, function) end
defp _map_tco(acc, [head | tail], function) do _map_tco([function.(head) | acc], tail, function) end
defp _map_tco(acc, [], _function) do acc end
def map_tco_concat(acc \\ [], list, function)
def map_tco_concat(acc, [head | tail], function) do map_tco_concat(acc ++ [function.(head)], tail, function) end
def map_tco_concat(acc, [], _function) do acc end
def map_tco_no_reverse(list, function) do _map_tco([], list, function) end
end
map_fun = fn(i) -> i + 1 end
inputs = %{
"1-Small 1 Thousand" => Enum.to_list(1..1_000),
"2-Middle 100 Thousand" => Enum.to_list(1..100_000),
"3-Big 10 Million" => Enum.to_list(1..10_000_000)
}
Benchee.run(%{
"tail" =>
fn list -> list |> MyMap.tail end,
"generic_tail fn" =>
fn list -> list |> MyMap.generic_tail(fn x -> x + 1 end) end,
"generic_tail &" =>
fn list -> list |> MyMap.generic_tail(&(&1 + 1)) end,
"bodyrecursive" =>
fn list -> list |> MyMap.bodyrecursive end,
"generic_bodyrecursive fn" =>
fn list -> list |> MyMap.generic_bodyrecursive(fn x -> x + 1 end) end,
"generic_bodyrecursive &" =>
fn list -> list |> MyMap.generic_bodyrecursive(&(&1 + 1)) end,
"stdlib fn" =>
fn list -> list |> Enum.map(fn x -> x + 1 end) end,
"stdlib &" =>
fn list -> list |> Enum.map(&(&1 + 1)) end,
"list comprehension" =>
fn list -> for x <- list do x + 1 end end,
"map with tail and reverse" =>
fn(list) -> MyMap.map_tco(list, map_fun) end,
"map tco no reverse" =>
fn(list) -> MyMap.map_tco_no_reverse(list, map_fun) end,
},
time: 15,
warmup: 5,
inputs: inputs,
formatters: [
&Benchee.Formatters.HTML.output/1,
&Benchee.Formatters.Console.output/1
],
html: [file: "report.html"]
)
# Erlang/OTP 19 [erts-8.2] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
# Elixir 1.4.1
# Benchmark suite executing with the following configuration:
# warmup: 5.0s
# time: 15.0s
# parallel: 1
# inputs: 1-Small 1 Thousand, 2-Middle 100 Thousand, 3-Big 10 Million
# Estimated total run time: 660.0s
# Benchmarking with input 1-Small 1 Thousand:
# Benchmarking bodyrecursive...
# Benchmarking generic_bodyrecursive &...
# Benchmarking generic_bodyrecursive fn...
# Benchmarking generic_tail &...
# Benchmarking generic_tail fn...
# Benchmarking list comprehension...
# Benchmarking map tco no reverse...
# Benchmarking map with tail and reverse...
# Benchmarking stdlib &...
# Benchmarking stdlib fn...
# Benchmarking tail...
# Benchmarking with input 2-Middle 100 Thousand:
# Benchmarking bodyrecursive...
# Benchmarking generic_bodyrecursive &...
# Benchmarking generic_bodyrecursive fn...
# Benchmarking generic_tail &...
# Benchmarking generic_tail fn...
# Benchmarking list comprehension...
# Benchmarking map tco no reverse...
# Benchmarking map with tail and reverse...
# Benchmarking stdlib &...
# Benchmarking stdlib fn...
# Benchmarking tail...
# Benchmarking with input 3-Big 10 Million:
# Benchmarking bodyrecursive...
# Benchmarking generic_bodyrecursive &...
# Benchmarking generic_bodyrecursive fn...
# Benchmarking generic_tail &...
# Benchmarking generic_tail fn...
# Benchmarking list comprehension...
# Benchmarking map tco no reverse...
# Benchmarking map with tail and reverse...
# Benchmarking stdlib &...
# Benchmarking stdlib fn...
# Benchmarking tail...
# Generated report_1-small_1_thousand.html
# Generated report_2-middle_100_thousand.html
# Generated report_3-big_10_million.html
# ##### With input 1-Small 1 Thousand #####
# Name ips average deviation median
# tail 63.07 K 15.85 μs ±195.72% 13.00 μs
# bodyrecursive 58.57 K 17.07 μs ±143.66% 15.00 μs
# generic_bodyrecursive & 56.47 K 17.71 μs ±121.19% 16.00 μs
# generic_bodyrecursive fn 55.32 K 18.08 μs ±119.32% 16.00 μs
# stdlib fn 30.56 K 32.73 μs ±128.55% 30.00 μs
# map tco no reverse 30.49 K 32.80 μs ±61.16% 31.00 μs
# stdlib & 28.34 K 35.28 μs ±72.55% 32.00 μs
# generic_tail fn 27.21 K 36.75 μs ±167.29% 32.00 μs
# list comprehension 26.55 K 37.67 μs ±394.51% 31.00 μs
# generic_tail & 26.48 K 37.76 μs ±64.60% 33.00 μs
# map with tail and reverse 25.80 K 38.75 μs ±145.98% 34.00 μs
# Comparison:
# tail 63.07 K
# bodyrecursive 58.57 K - 1.08x slower
# generic_bodyrecursive & 56.47 K - 1.12x slower
# generic_bodyrecursive fn 55.32 K - 1.14x slower
# stdlib fn 30.56 K - 2.06x slower
# map tco no reverse 30.49 K - 2.07x slower
# stdlib & 28.34 K - 2.23x slower
# generic_tail fn 27.21 K - 2.32x slower
# list comprehension 26.55 K - 2.38x slower
# generic_tail & 26.48 K - 2.38x slower
# map with tail and reverse 25.80 K - 2.44x slower
# ##### With input 2-Middle 100 Thousand #####
# Name ips average deviation median
# generic_bodyrecursive & 519.02 1.93 ms ±20.57% 1.79 ms
# generic_bodyrecursive fn 499.03 2.00 ms ±46.20% 1.89 ms
# bodyrecursive 494.41 2.02 ms ±21.15% 1.91 ms
# tail 428.99 2.33 ms ±40.93% 2.13 ms
# stdlib & 261.78 3.82 ms ±19.01% 3.63 ms
# map tco no reverse 257.84 3.88 ms ±30.36% 3.65 ms
# stdlib fn 245.02 4.08 ms ±24.77% 3.83 ms
# generic_tail & 237.28 4.21 ms ±30.86% 3.92 ms
# list comprehension 234.36 4.27 ms ±28.82% 4.00 ms
# generic_tail fn 215.86 4.63 ms ±37.15% 4.29 ms
# map with tail and reverse 197.28 5.07 ms ±40.31% 4.73 ms
# Comparison:
# generic_bodyrecursive & 519.02
# generic_bodyrecursive fn 499.03 - 1.04x slower
# bodyrecursive 494.41 - 1.05x slower
# tail 428.99 - 1.21x slower
# stdlib & 261.78 - 1.98x slower
# map tco no reverse 257.84 - 2.01x slower
# stdlib fn 245.02 - 2.12x slower
# generic_tail & 237.28 - 2.19x slower
# list comprehension 234.36 - 2.21x slower
# generic_tail fn 215.86 - 2.40x slower
# map with tail and reverse 197.28 - 2.63x slower
# ##### With input 3-Big 10 Million #####
# Name ips average deviation median
# map tco no reverse 2.51 399.11 ms ±19.71% 373.50 ms
# tail 1.84 543.93 ms ±41.75% 486.18 ms
# list comprehension 1.41 707.87 ms ±19.18% 675.98 ms
# map with tail and reverse 1.40 714.90 ms ±18.26% 686.56 ms
# generic_tail fn 1.40 714.99 ms ±21.67% 666.39 ms
# generic_tail & 1.20 832.02 ms ±24.42% 803.23 ms
# generic_bodyrecursive fn 0.98 1015.60 ms ±22.63% 1056.96 ms
# generic_bodyrecursive & 0.90 1114.73 ms ±24.02% 1130.33 ms
# stdlib & 0.88 1142.06 ms ±19.41% 1219.39 ms
# stdlib fn 0.87 1145.33 ms ±19.42% 1231.18 ms
# bodyrecursive 0.77 1292.77 ms ±23.20% 1342.22 ms
# Comparison:
# map tco no reverse 2.51
# tail 1.84 - 1.36x slower
# list comprehension 1.41 - 1.77x slower
# map with tail and reverse 1.40 - 1.79x slower
# generic_tail fn 1.40 - 1.79x slower
# generic_tail & 1.20 - 2.08x slower
# generic_bodyrecursive fn 0.98 - 2.54x slower
# generic_bodyrecursive & 0.90 - 2.79x slower
# stdlib & 0.88 - 2.86x slower
# stdlib fn 0.87 - 2.87x slower
# bodyrecursive 0.77 - 3.24x slower
# ------------------------------------------------------------------------------
# Erlang/OTP 19 [erts-8.2] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
# Elixir 1.4.1
# Benchmark suite executing with the following configuration:
# warmup: 2.0s
# time: 5.0s
# parallel: 1
# inputs: 1-Small 1 Thousand, 2-Middle 100 Thousand, 3-Big 10 Million
# Estimated total run time: 231.0s
# Benchmarking with input 1-Small 1 Thousand:
# Benchmarking bodyrecursive...
# Benchmarking generic_bodyrecursive &...
# Benchmarking generic_bodyrecursive fn...
# Benchmarking generic_tail &...
# Benchmarking generic_tail fn...
# Benchmarking list comprehension...
# Benchmarking map tco no reverse...
# Benchmarking map with tail and reverse...
# Benchmarking stdlib &...
# Benchmarking stdlib fn...
# Benchmarking tail...
# Benchmarking with input 2-Middle 100 Thousand:
# Benchmarking bodyrecursive...
# Benchmarking generic_bodyrecursive &...
# Benchmarking generic_bodyrecursive fn...
# Benchmarking generic_tail &...
# Benchmarking generic_tail fn...
# Benchmarking list comprehension...
# Benchmarking map tco no reverse...
# Benchmarking map with tail and reverse...
# Benchmarking stdlib &...
# Benchmarking stdlib fn...
# Benchmarking tail...
# Benchmarking with input 3-Big 10 Million:
# Benchmarking bodyrecursive...
# Benchmarking generic_bodyrecursive &...
# Benchmarking generic_bodyrecursive fn...
# Benchmarking generic_tail &...
# Benchmarking generic_tail fn...
# Benchmarking list comprehension...
# Benchmarking map tco no reverse...
# Benchmarking map with tail and reverse...
# Benchmarking stdlib &...
# Benchmarking stdlib fn...
# Benchmarking tail...
# Generated report_1_-_small_-_1_thousand.html
# Generated report_2_-_middle_-_100_thousand.html
# Generated report_3_-_big_-_10_million.html
# ##### With input 1-Small 1 Thousand #####
# Name ips average deviation median
# tail 75.77 K 13.20 μs ±192.88% 12.00 μs
# generic_bodyrecursive & 59.03 K 16.94 μs ±86.31% 15.00 μs
# bodyrecursive 58.86 K 16.99 μs ±52.39% 15.00 μs
# generic_bodyrecursive fn 55.99 K 17.86 μs ±131.17% 15.00 μs
# stdlib fn 31.56 K 31.69 μs ±176.10% 29.00 μs
# stdlib & 30.89 K 32.37 μs ±66.49% 29.00 μs
# list comprehension 30.83 K 32.44 μs ±160.79% 31.00 μs
# generic_tail & 28.86 K 34.65 μs ±64.41% 33.00 μs
# map tco no reverse 28.77 K 34.75 μs ±49.77% 33.00 μs
# generic_tail fn 28.55 K 35.03 μs ±57.88% 33.00 μs
# map with tail and reverse 26.55 K 37.67 μs ±57.48% 36.00 μs
# Comparison:
# tail 75.77 K
# generic_bodyrecursive & 59.03 K - 1.28x slower
# bodyrecursive 58.86 K - 1.29x slower
# generic_bodyrecursive fn 55.99 K - 1.35x slower
# stdlib fn 31.56 K - 2.40x slower
# stdlib & 30.89 K - 2.45x slower
# list comprehension 30.83 K - 2.46x slower
# generic_tail & 28.86 K - 2.63x slower
# map tco no reverse 28.77 K - 2.63x slower
# generic_tail fn 28.55 K - 2.65x slower
# map with tail and reverse 26.55 K - 2.85x slower
# ##### With input 2-Middle 100 Thousand #####
# Name ips average deviation median
# generic_bodyrecursive & 570.31 1.75 ms ±15.47% 1.70 ms
# bodyrecursive 568.73 1.76 ms ±14.63% 1.70 ms
# generic_bodyrecursive fn 568.31 1.76 ms ±15.54% 1.70 ms
# tail 500.11 2.00 ms ±37.82% 1.94 ms
# stdlib & 309.28 3.23 ms ±13.17% 3.07 ms
# stdlib fn 304.57 3.28 ms ±13.54% 3.13 ms
# map tco no reverse 300.33 3.33 ms ±13.53% 3.17 ms
# list comprehension 273.91 3.65 ms ±24.43% 3.45 ms
# generic_tail & 259.20 3.86 ms ±22.43% 3.65 ms
# generic_tail fn 258.28 3.87 ms ±22.23% 3.68 ms
# map with tail and reverse 241.47 4.14 ms ±21.75% 3.91 ms
# Comparison:
# generic_bodyrecursive & 570.31
# bodyrecursive 568.73 - 1.00x slower
# generic_bodyrecursive fn 568.31 - 1.00x slower
# tail 500.11 - 1.14x slower
# stdlib & 309.28 - 1.84x slower
# stdlib fn 304.57 - 1.87x slower
# map tco no reverse 300.33 - 1.90x slower
# list comprehension 273.91 - 2.08x slower
# generic_tail & 259.20 - 2.20x slower
# generic_tail fn 258.28 - 2.21x slower
# map with tail and reverse 241.47 - 2.36x slower
# ##### With input 3-Big 10 Million #####
# Name ips average deviation median
# map tco no reverse 2.14 466.34 ms ±20.14% 437.61 ms
# tail 2.13 468.99 ms ±38.22% 396.29 ms
# list comprehension 1.56 639.71 ms ±31.52% 644.18 ms
# map with tail and reverse 1.42 703.56 ms ±30.40% 700.50 ms
# generic_tail fn 1.29 777.66 ms ±27.21% 714.83 ms
# generic_tail & 1.15 872.69 ms ±21.90% 923.20 ms
# generic_bodyrecursive & 1.07 933.02 ms ±33.35% 1066.12 ms
# bodyrecursive 1.04 960.28 ms ±31.39% 1051.07 ms
# generic_bodyrecursive fn 1.04 960.88 ms ±32.64% 1090.40 ms
# stdlib fn 1.03 970.59 ms ±30.63% 1176.81 ms
# stdlib & 1.00 998.24 ms ±33.43% 1187.14 ms
# Comparison:
# map tco no reverse 2.14
# tail 2.13 - 1.01x slower
# list comprehension 1.56 - 1.37x slower
# map with tail and reverse 1.42 - 1.51x slower
# generic_tail fn 1.29 - 1.67x slower
# generic_tail & 1.15 - 1.87x slower
# generic_bodyrecursive & 1.07 - 2.00x slower
# bodyrecursive 1.04 - 2.06x slower
# generic_bodyrecursive fn 1.04 - 2.06x slower
# stdlib fn 1.03 - 2.08x slower
# stdlib & 1.00 - 2.14x slower
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment