Skip to content

Instantly share code, notes, and snippets.

@weapp
Last active February 27, 2017 15:44

Revisions

  1. weapp revised this gist Feb 27, 2017. 1 changed file with 19 additions and 19 deletions.
    38 changes: 19 additions & 19 deletions maps_bench.ex
    Original file line number Diff line number Diff line change
    @@ -145,7 +145,7 @@ Benchee.run(%{
    # 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:
    # Comparison:
    # tail 63.07 K
    # bodyrecursive 58.57 K - 1.08x slower
    # generic_bodyrecursive & 56.47 K - 1.12x slower
    @@ -161,7 +161,7 @@ Benchee.run(%{
    # ##### With input 2-Middle 100 Thousand #####
    # Name ips average deviation median
    # generic_bodyrecursive & 519.02 1.93 ms ±20.57% 1.79 ms
    # d fn 499.03 2.00 ms ±46.20% 1.89 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
    @@ -172,9 +172,9 @@ Benchee.run(%{
    # 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:
    # d & 519.02
    # d fn 499.03 - 1.04x slower
    # 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
    @@ -193,21 +193,21 @@ Benchee.run(%{
    # 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
    # d fn 0.98 1015.60 ms ±22.63% 1056.96 ms
    # d & 0.90 1114.73 ms ±24.02% 1130.33 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:
    # 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
    # d fn 0.98 - 2.54x slower
    # d & 0.90 - 2.79x 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
    @@ -230,8 +230,8 @@ Benchee.run(%{

    # Benchmarking with input 1-Small 1 Thousand:
    # Benchmarking bodyrecursive...
    # Benchmarking d &...
    # Benchmarking d fn...
    # Benchmarking generic_bodyrecursive &...
    # Benchmarking generic_bodyrecursive fn...
    # Benchmarking generic_tail &...
    # Benchmarking generic_tail fn...
    # Benchmarking list comprehension...
    @@ -243,8 +243,8 @@ Benchee.run(%{

    # Benchmarking with input 2-Middle 100 Thousand:
    # Benchmarking bodyrecursive...
    # Benchmarking d &...
    # Benchmarking d fn...
    # Benchmarking generic_bodyrecursive &...
    # Benchmarking generic_bodyrecursive fn...
    # Benchmarking generic_tail &...
    # Benchmarking generic_tail fn...
    # Benchmarking list comprehension...
    @@ -256,8 +256,8 @@ Benchee.run(%{

    # Benchmarking with input 3-Big 10 Million:
    # Benchmarking bodyrecursive...
    # Benchmarking d &...
    # Benchmarking d fn...
    # Benchmarking generic_bodyrecursive &...
    # Benchmarking generic_bodyrecursive fn...
    # Benchmarking generic_tail &...
    # Benchmarking generic_tail fn...
    # Benchmarking list comprehension...
    @@ -273,9 +273,9 @@ Benchee.run(%{
    # ##### With input 1-Small 1 Thousand #####
    # Name ips average deviation median
    # tail 75.77 K 13.20 μs ±192.88% 12.00 μs
    # d & 59.03 K 16.94 μs ±86.31% 15.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
    # d fn 55.99 K 17.86 μs ±131.17% 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
    @@ -286,7 +286,7 @@ Benchee.run(%{

    # Comparison:
    # tail 75.77 K
    # d & 59.03 K - 1.28x slower
    # 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
  2. weapp created this gist Feb 27, 2017.
    352 changes: 352 additions & 0 deletions maps_bench.ex
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,352 @@
    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
    # d 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:
    # d & 519.02
    # d 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
    # d fn 0.98 1015.60 ms ±22.63% 1056.96 ms
    # d & 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
    # d fn 0.98 - 2.54x slower
    # d & 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 d &...
    # Benchmarking d 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 d &...
    # Benchmarking d 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 d &...
    # Benchmarking d 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
    # d & 59.03 K 16.94 μs ±86.31% 15.00 μs
    # bodyrecursive 58.86 K 16.99 μs ±52.39% 15.00 μs
    # d 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
    # d & 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