Last active
July 16, 2016 02:01
-
-
Save eksperimental/3f9c58a5b27fa9ff05abcd1df4678b1a to your computer and use it in GitHub Desktop.
Enum.fetch/2 Optimizations
This file contains 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
defmodule EnumFetchHelpers do | |
## fetch | |
def fetch_list([], _index), | |
do: :error | |
def fetch_list([head | _], 0), | |
do: {:ok, head} | |
def fetch_list([_ | tail], index), | |
do: fetch_list(tail, index - 1) | |
def fetch_range(first, last, index) when first <= last and index >= 0 do | |
item = first + index | |
if item > last, do: :error, else: {:ok, item} | |
end | |
def fetch_range(first, last, index) when first <= last do | |
item = last + index + 1 | |
if item < first, do: :error, else: {:ok, item} | |
end | |
def fetch_range(first, last, index) when index >= 0 do | |
item = first - index | |
if item < last, do: :error, else: {:ok, item} | |
end | |
def fetch_range(first, last, index) do | |
item = last - index - 1 | |
if item > first, do: :error, else: {:ok, item} | |
end | |
def fetch_enumerable(enumerable, index, module) do | |
reduce_res = | |
module.reduce(enumerable, {:cont, 0}, fn | |
entry, ^index -> | |
{:halt, entry} | |
_entry, acc -> | |
{:cont, acc + 1} | |
end) | |
case reduce_res do | |
{:halted, entry} -> {:ok, entry} | |
{:done, _} -> :error | |
end | |
end | |
end | |
defmodule EnumFetch.Original do | |
import EnumFetchHelpers | |
def fetch(enumerable, index) | |
def fetch(first..last, index) when is_integer(index) do | |
fetch_range(first, last, index) | |
end | |
def fetch(enumerable, index) when is_integer(index) and index < 0 do | |
case Enumerable.count(enumerable) do | |
{:error, _} -> | |
enumerable | |
|> Enum.reverse | |
|> fetch_list((-index) - 1) | |
{:ok, count} when (count + index) < 0 -> | |
:error | |
{:ok, count} -> | |
fetch_enumerable(enumerable, count + index, Enumerable) | |
end | |
end | |
def fetch(enumerable, index) when is_list(enumerable) and is_integer(index) do | |
fetch_list(enumerable, index) | |
end | |
def fetch(enumerable, index) when is_integer(index) do | |
count_result = | |
case Enumerable.count(enumerable) do | |
{:error, module} -> | |
{:ok, module} | |
{:ok, count} when (count - 1 - index) < 0 -> | |
:error | |
{:ok, _} -> | |
{:ok, Enumerable} | |
end | |
case count_result do | |
:error -> | |
:error | |
{:ok, module} -> | |
fetch_enumerable(enumerable, index, module) | |
end | |
end | |
end | |
defmodule EnumFetch.Master do | |
import EnumFetchHelpers | |
def fetch(enumerable, index) | |
def fetch(first..last, index) when is_integer(index) do | |
fetch_range(first, last, index) | |
end | |
def fetch(enumerable, index) when is_integer(index) and index < 0 do | |
case enumerable do | |
enumerable when is_list(enumerable) -> | |
enumerable | |
|> :lists.reverse | |
|> fetch_list((-index) - 1) | |
_ -> | |
case Enumerable.count(enumerable) do | |
{:error, _} -> | |
enumerable | |
|> Enum.reverse | |
|> fetch_list((-index) - 1) | |
{:ok, count} when (count + index) < 0 -> | |
:error | |
{:ok, count} -> | |
fetch_enumerable(enumerable, count + index, Enumerable) | |
end | |
end | |
end | |
def fetch(enumerable, index) when is_list(enumerable) and is_integer(index) do | |
fetch_list(enumerable, index) | |
end | |
def fetch(enumerable, index) when is_integer(index) do | |
count_result = | |
case Enumerable.count(enumerable) do | |
{:error, module} -> | |
{:ok, module} | |
{:ok, count} when count <= index -> | |
:error | |
{:ok, _} -> | |
{:ok, Enumerable} | |
end | |
case count_result do | |
:error -> | |
:error | |
{:ok, module} -> | |
fetch_enumerable(enumerable, index, module) | |
end | |
end | |
end | |
defmodule EnumFetch.RangeOptimized do | |
import EnumFetchHelpers | |
def fetch(enumerable, index) | |
def fetch(enumerable, index) when is_integer(index) and index < 0 do | |
case enumerable do | |
enumerable when is_list(enumerable) -> | |
enumerable | |
|> :lists.reverse | |
|> fetch_list((-index) - 1) | |
first..last -> | |
fetch_range(first, last, index) | |
_ -> | |
case Enumerable.count(enumerable) do | |
{:error, _} -> | |
enumerable | |
|> Enum.reverse | |
|> fetch_list((-index) - 1) | |
{:ok, count} when (count + index) < 0 -> | |
:error | |
{:ok, count} -> | |
fetch_enumerable(enumerable, count + index, Enumerable) | |
end | |
end | |
end | |
def fetch(enumerable, index) when is_list(enumerable) and is_integer(index) do | |
fetch_list(enumerable, index) | |
end | |
def fetch(first..last, index) when is_integer(index) do | |
fetch_range(first, last, index) | |
end | |
def fetch(enumerable, index) when is_integer(index) do | |
count_result = | |
case Enumerable.count(enumerable) do | |
{:error, module} -> | |
{:ok, module} | |
{:ok, count} when count <= index -> | |
:error | |
{:ok, _} -> | |
{:ok, Enumerable} | |
end | |
case count_result do | |
:error -> | |
:error | |
{:ok, module} -> | |
fetch_enumerable(enumerable, index, module) | |
end | |
end | |
end |
This file contains 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
$ exenv local master && | |
> MODULE=EnumFetch.Original mix bench bench/enum_fetch_with_range_bench.exs -d 3 && | |
> MODULE=EnumFetch.Master mix bench bench/enum_fetch_with_range_bench.exs -d 3 && | |
> mix bench.cmp -d percent && | |
> MODULE=EnumFetch.RangeOptimized mix bench bench/enum_fetch_with_range_bench.exs -d 3 && | |
> mix bench.cmp -d percent | |
Enum.fetch/2 - Elixir v1.4.0-dev (8b99214) | |
EnumFetch.Original | |
Settings: | |
duration: 3.0 s | |
Finished in 1766.83 seconds | |
## :"list (1000 elem)" | |
benchmark name iterations average time | |
first 100000000 0.07 µs/op | |
last (neg index) 1000000 4.16 µs/op | |
middle 1000000 5.35 µs/op | |
middle (neg index) 500000 9.53 µs/op | |
last 500000 10.47 µs/op | |
out of bound (neg index) 500000 14.59 µs/op | |
first (neg index) 500000 14.77 µs/op | |
out of bound 500000 15.14 µs/op | |
## :"list_big (100000 elem)" | |
benchmark name iterations average time | |
first 100000000 0.07 µs/op | |
last (neg index) 10000 346.60 µs/op | |
middle 10000 538.18 µs/op | |
middle (neg index) 10000 914.96 µs/op | |
last 5000 1057.08 µs/op | |
first (neg index) 5000 1423.94 µs/op | |
out of bound (neg index) 5000 1436.50 µs/op | |
out of bound 5000 1443.69 µs/op | |
## :"list_empty (0 elem)" | |
benchmark name iterations average time | |
middle 100000000 0.06 µs/op | |
first 100000000 0.06 µs/op | |
middle (neg index) 100000000 0.06 µs/op | |
first (neg index) 100000000 0.06 µs/op | |
last 100000000 0.14 µs/op | |
out of bound 100000000 0.14 µs/op | |
last (neg index) 100000000 0.15 µs/op | |
out of bound (neg index) 100000000 0.15 µs/op | |
## :"list_huge (600000 elem)" | |
benchmark name iterations average time | |
first 100000000 0.07 µs/op | |
middle 1000 3260.61 µs/op | |
last (neg index) 1000 4764.12 µs/op | |
last 1000 6515.04 µs/op | |
middle (neg index) 1000 7881.37 µs/op | |
out of bound (neg index) 500 10994.97 µs/op | |
first (neg index) 500 11079.70 µs/op | |
out of bound 500 11117.98 µs/op | |
## :"list_single (1 elem)" | |
benchmark name iterations average time | |
middle 100000000 0.07 µs/op | |
first 100000000 0.07 µs/op | |
middle (neg index) 100000000 0.07 µs/op | |
first (neg index) 100000000 0.07 µs/op | |
last 100000000 0.07 µs/op | |
out of bound 100000000 0.15 µs/op | |
out of bound (neg index) 100000000 0.16 µs/op | |
last (neg index) 100000000 0.16 µs/op | |
## :"map (1000 elem)" | |
benchmark name iterations average time | |
out of bound 100000000 0.17 µs/op | |
out of bound (neg index) 100000000 0.17 µs/op | |
first 200000 25.31 µs/op | |
first (neg index) 200000 25.38 µs/op | |
middle (neg index) 100000 57.45 µs/op | |
middle 100000 59.32 µs/op | |
last 100000 85.85 µs/op | |
last (neg index) 100000 85.99 µs/op | |
## :"map_big (100000 elem)" | |
benchmark name iterations average time | |
out of bound 100000000 0.17 µs/op | |
out of bound (neg index) 100000000 0.18 µs/op | |
first 1000 3009.99 µs/op | |
first (neg index) 1000 3047.80 µs/op | |
middle 1000 6159.42 µs/op | |
middle (neg index) 1000 6162.58 µs/op | |
last 500 9034.61 µs/op | |
last (neg index) 500 9045.05 µs/op | |
## :"map_empty (0 elem)" | |
benchmark name iterations average time | |
last 100000000 0.16 µs/op | |
out of bound 100000000 0.16 µs/op | |
middle (neg index) 100000000 0.16 µs/op | |
last (neg index) 100000000 0.16 µs/op | |
first 100000000 0.16 µs/op | |
out of bound (neg index) 100000000 0.16 µs/op | |
first (neg index) 100000000 0.17 µs/op | |
middle 100000000 0.22 µs/op | |
## :"map_huge (600000 elem)" | |
benchmark name iterations average time | |
out of bound 100000000 0.25 µs/op | |
out of bound (neg index) 100000000 0.25 µs/op | |
first 500 19194.09 µs/op | |
first (neg index) 500 19226.47 µs/op | |
middle (neg index) 100 40319.46 µs/op | |
middle 100 40695.40 µs/op | |
last 100 58992.48 µs/op | |
last (neg index) 100 60408.67 µs/op | |
## :"map_single (1 elem)" | |
benchmark name iterations average time | |
out of bound (neg index) 100000000 0.16 µs/op | |
out of bound 100000000 0.17 µs/op | |
first (neg index) 10000000 0.56 µs/op | |
last 10000000 0.56 µs/op | |
middle 10000000 0.57 µs/op | |
middle (neg index) 10000000 0.57 µs/op | |
first 10000000 0.57 µs/op | |
last (neg index) 10000000 0.57 µs/op | |
## :"range (1000 elem)" | |
benchmark name iterations average time | |
last 100000000 0.10 µs/op | |
first 100000000 0.10 µs/op | |
out of bound (neg index) 100000000 0.10 µs/op | |
out of bound 100000000 0.11 µs/op | |
middle 100000000 0.11 µs/op | |
middle (neg index) 100000000 0.11 µs/op | |
first (neg index) 100000000 0.11 µs/op | |
last (neg index) 100000000 0.12 µs/op | |
## :"range_big (100000 elem)" | |
benchmark name iterations average time | |
last 100000000 0.10 µs/op | |
first 100000000 0.10 µs/op | |
out of bound (neg index) 100000000 0.10 µs/op | |
out of bound 100000000 0.11 µs/op | |
middle 100000000 0.11 µs/op | |
first (neg index) 100000000 0.12 µs/op | |
last (neg index) 100000000 0.12 µs/op | |
middle (neg index) 100000000 0.12 µs/op | |
## :"range_huge (600000 elem)" | |
benchmark name iterations average time | |
first 100000000 0.10 µs/op | |
last 100000000 0.11 µs/op | |
middle 100000000 0.11 µs/op | |
out of bound (neg index) 100000000 0.11 µs/op | |
out of bound 100000000 0.11 µs/op | |
last (neg index) 100000000 0.12 µs/op | |
middle (neg index) 100000000 0.12 µs/op | |
first (neg index) 100000000 0.12 µs/op | |
## :"range_single (1 elem)" | |
benchmark name iterations average time | |
first (neg index) 100000000 0.09 µs/op | |
first 100000000 0.09 µs/op | |
middle 100000000 0.10 µs/op | |
last 100000000 0.10 µs/op | |
middle (neg index) 100000000 0.10 µs/op | |
out of bound (neg index) 100000000 0.10 µs/op | |
last (neg index) 100000000 0.10 µs/op | |
out of bound 100000000 0.11 µs/op | |
## :"struct (1000 elem)" | |
benchmark name iterations average time | |
out of bound (neg index) 100000000 0.21 µs/op | |
out of bound 100000000 0.22 µs/op | |
first (neg index) 500000 21.63 µs/op | |
first 500000 22.03 µs/op | |
middle (neg index) 100000 54.82 µs/op | |
middle 100000 56.66 µs/op | |
last (neg index) 100000 87.20 µs/op | |
last 50000 88.43 µs/op | |
## :"struct_big (100000 elem)" | |
benchmark name iterations average time | |
out of bound (neg index) 100000000 0.21 µs/op | |
out of bound 100000000 0.22 µs/op | |
first (neg index) 2000 2459.00 µs/op | |
first 2000 2466.46 µs/op | |
middle 1000 5686.36 µs/op | |
middle (neg index) 1000 5794.17 µs/op | |
last (neg index) 1000 9034.94 µs/op | |
last 500 9441.61 µs/op | |
## :"struct_empty (0 elem)" | |
benchmark name iterations average time | |
out of bound 100000000 0.20 µs/op | |
out of bound (neg index) 100000000 0.20 µs/op | |
last (neg index) 100000000 0.20 µs/op | |
middle 100000000 0.20 µs/op | |
middle (neg index) 100000000 0.20 µs/op | |
last 100000000 0.20 µs/op | |
first (neg index) 100000000 0.21 µs/op | |
first 100000000 0.23 µs/op | |
## :"struct_huge (600000 elem)" | |
benchmark name iterations average time | |
out of bound 100000000 0.19 µs/op | |
out of bound (neg index) 100000000 0.20 µs/op | |
first (neg index) 500 15059.91 µs/op | |
first 500 15087.19 µs/op | |
middle 100 33653.49 µs/op | |
middle (neg index) 100 37083.41 µs/op | |
last (neg index) 100 56763.04 µs/op | |
last 100 58278.36 µs/op | |
## :"struct_single (1 elem)" | |
benchmark name iterations average time | |
out of bound (neg index) 100000000 0.19 µs/op | |
out of bound 100000000 0.20 µs/op | |
last (neg index) 10000000 0.66 µs/op | |
middle (neg index) 10000000 0.67 µs/op | |
last 10000000 0.67 µs/op | |
first 10000000 0.68 µs/op | |
first (neg index) 10000000 0.69 µs/op | |
middle 10000000 0.70 µs/op | |
Enum.fetch/2 - Elixir v1.4.0-dev (8b99214) | |
EnumFetch.Master | |
Settings: | |
duration: 3.0 s | |
Finished in 1699.29 seconds | |
## :"list (1000 elem)" | |
benchmark name iterations average time | |
first 100000000 0.07 µs/op | |
last (neg index) 1000000 4.06 µs/op | |
middle 1000000 5.35 µs/op | |
middle (neg index) 500000 9.35 µs/op | |
last 500000 10.64 µs/op | |
out of bound (neg index) 500000 14.67 µs/op | |
out of bound 500000 14.97 µs/op | |
first (neg index) 500000 15.02 µs/op | |
## :"list_big (100000 elem)" | |
benchmark name iterations average time | |
first 100000000 0.07 µs/op | |
last (neg index) 10000 345.94 µs/op | |
middle 10000 520.68 µs/op | |
middle (neg index) 10000 923.72 µs/op | |
last 5000 1045.81 µs/op | |
out of bound (neg index) 5000 1413.51 µs/op | |
out of bound 5000 1421.82 µs/op | |
first (neg index) 5000 1433.49 µs/op | |
## :"list_empty (0 elem)" | |
benchmark name iterations average time | |
middle 100000000 0.06 µs/op | |
first 100000000 0.06 µs/op | |
middle (neg index) 100000000 0.06 µs/op | |
first (neg index) 100000000 0.06 µs/op | |
out of bound 100000000 0.08 µs/op | |
out of bound (neg index) 100000000 0.08 µs/op | |
last 100000000 0.08 µs/op | |
last (neg index) 100000000 0.08 µs/op | |
## :"list_huge (600000 elem)" | |
benchmark name iterations average time | |
first 100000000 0.07 µs/op | |
middle 1000 3274.91 µs/op | |
last (neg index) 1000 4763.99 µs/op | |
last 1000 6403.23 µs/op | |
middle (neg index) 1000 8090.50 µs/op | |
first (neg index) 500 11045.05 µs/op | |
out of bound 500 11088.33 µs/op | |
out of bound (neg index) 500 11251.57 µs/op | |
## :"list_single (1 elem)" | |
benchmark name iterations average time | |
middle 100000000 0.07 µs/op | |
middle (neg index) 100000000 0.07 µs/op | |
first (neg index) 100000000 0.07 µs/op | |
first 100000000 0.07 µs/op | |
last 100000000 0.07 µs/op | |
out of bound (neg index) 100000000 0.10 µs/op | |
out of bound 100000000 0.10 µs/op | |
last (neg index) 100000000 0.10 µs/op | |
## :"map (1000 elem)" | |
benchmark name iterations average time | |
out of bound (neg index) 100000000 0.19 µs/op | |
out of bound 100000000 0.20 µs/op | |
first 200000 25.07 µs/op | |
first (neg index) 200000 26.83 µs/op | |
middle (neg index) 100000 60.74 µs/op | |
middle 100000 60.82 µs/op | |
last 50000 86.65 µs/op | |
last (neg index) 50000 90.79 µs/op | |
## :"map_big (100000 elem)" | |
benchmark name iterations average time | |
out of bound (neg index) 100000000 0.19 µs/op | |
out of bound 100000000 0.21 µs/op | |
first (neg index) 1000 3120.36 µs/op | |
first 1000 3198.35 µs/op | |
middle 1000 6418.44 µs/op | |
middle (neg index) 1000 6583.23 µs/op | |
last (neg index) 500 9367.90 µs/op | |
last 500 9951.25 µs/op | |
## :"map_empty (0 elem)" | |
benchmark name iterations average time | |
middle (neg index) 100000000 0.15 µs/op | |
first 100000000 0.16 µs/op | |
out of bound (neg index) 100000000 0.16 µs/op | |
out of bound 100000000 0.16 µs/op | |
last 100000000 0.17 µs/op | |
middle 100000000 0.17 µs/op | |
first (neg index) 100000000 0.18 µs/op | |
last (neg index) 100000000 0.19 µs/op | |
## :"map_huge (600000 elem)" | |
benchmark name iterations average time | |
out of bound (neg index) 100000000 0.22 µs/op | |
out of bound 100000000 0.22 µs/op | |
first 500 18135.10 µs/op | |
first (neg index) 500 18778.54 µs/op | |
middle (neg index) 100 39214.16 µs/op | |
middle 100 42085.96 µs/op | |
last 100 59020.51 µs/op | |
last (neg index) 100 59067.88 µs/op | |
## :"map_single (1 elem)" | |
benchmark name iterations average time | |
out of bound (neg index) 100000000 0.16 µs/op | |
out of bound 100000000 0.17 µs/op | |
middle 10000000 0.52 µs/op | |
last 10000000 0.52 µs/op | |
first (neg index) 10000000 0.53 µs/op | |
middle (neg index) 10000000 0.54 µs/op | |
first 10000000 0.55 µs/op | |
last (neg index) 10000000 0.61 µs/op | |
## :"range (1000 elem)" | |
benchmark name iterations average time | |
last 100000000 0.10 µs/op | |
first 100000000 0.10 µs/op | |
out of bound (neg index) 100000000 0.10 µs/op | |
out of bound 100000000 0.10 µs/op | |
middle 100000000 0.11 µs/op | |
first (neg index) 100000000 0.11 µs/op | |
last (neg index) 100000000 0.11 µs/op | |
middle (neg index) 100000000 0.12 µs/op | |
## :"range_big (100000 elem)" | |
benchmark name iterations average time | |
last 100000000 0.10 µs/op | |
first 100000000 0.10 µs/op | |
out of bound (neg index) 100000000 0.10 µs/op | |
out of bound 100000000 0.10 µs/op | |
middle 100000000 0.11 µs/op | |
first (neg index) 100000000 0.11 µs/op | |
last (neg index) 100000000 0.12 µs/op | |
middle (neg index) 100000000 0.12 µs/op | |
## :"range_huge (600000 elem)" | |
benchmark name iterations average time | |
last 100000000 0.10 µs/op | |
first 100000000 0.10 µs/op | |
out of bound (neg index) 100000000 0.10 µs/op | |
out of bound 100000000 0.10 µs/op | |
middle 100000000 0.11 µs/op | |
last (neg index) 100000000 0.11 µs/op | |
middle (neg index) 100000000 0.12 µs/op | |
first (neg index) 100000000 0.12 µs/op | |
## :"range_single (1 elem)" | |
benchmark name iterations average time | |
first 100000000 0.09 µs/op | |
middle (neg index) 100000000 0.09 µs/op | |
first (neg index) 100000000 0.09 µs/op | |
middle 100000000 0.09 µs/op | |
out of bound 100000000 0.09 µs/op | |
out of bound (neg index) 100000000 0.09 µs/op | |
last 100000000 0.10 µs/op | |
last (neg index) 100000000 0.10 µs/op | |
## :"struct (1000 elem)" | |
benchmark name iterations average time | |
out of bound (neg index) 100000000 0.19 µs/op | |
out of bound 100000000 0.19 µs/op | |
first 500000 20.92 µs/op | |
first (neg index) 500000 22.00 µs/op | |
middle 100000 51.31 µs/op | |
middle (neg index) 100000 51.51 µs/op | |
last (neg index) 100000 82.92 µs/op | |
last 50000 88.60 µs/op | |
## :"struct_big (100000 elem)" | |
benchmark name iterations average time | |
out of bound 100000000 0.22 µs/op | |
out of bound (neg index) 10000000 0.35 µs/op | |
first 2000 2447.22 µs/op | |
first (neg index) 2000 2485.71 µs/op | |
middle 1000 5487.25 µs/op | |
middle (neg index) 1000 5585.73 µs/op | |
last 1000 8540.50 µs/op | |
last (neg index) 1000 8685.98 µs/op | |
## :"struct_empty (0 elem)" | |
benchmark name iterations average time | |
middle (neg index) 100000000 0.19 µs/op | |
middle 100000000 0.21 µs/op | |
first 100000000 0.21 µs/op | |
out of bound (neg index) 100000000 0.22 µs/op | |
first (neg index) 100000000 0.22 µs/op | |
out of bound 100000000 0.23 µs/op | |
last (neg index) 100000000 0.23 µs/op | |
last 100000000 0.23 µs/op | |
## :"struct_huge (600000 elem)" | |
benchmark name iterations average time | |
out of bound 100000000 0.20 µs/op | |
out of bound (neg index) 100000000 0.22 µs/op | |
first (neg index) 500 15460.94 µs/op | |
first 500 15639.35 µs/op | |
middle (neg index) 100 33657.75 µs/op | |
middle 100 37557.05 µs/op | |
last 100 54787.05 µs/op | |
last (neg index) 100 55799.23 µs/op | |
## :"struct_single (1 elem)" | |
benchmark name iterations average time | |
out of bound (neg index) 100000000 0.22 µs/op | |
out of bound 100000000 0.22 µs/op | |
first (neg index) 10000000 0.67 µs/op | |
middle (neg index) 10000000 0.67 µs/op | |
first 10000000 0.68 µs/op | |
middle 10000000 0.68 µs/op | |
last 10000000 0.68 µs/op | |
last (neg index) 10000000 0.70 µs/op | |
bench/snapshots/2016-07-15_23-13-57.snapshot vs | |
bench/snapshots/2016-07-15_23-42-37.snapshot | |
## :"list (1000 elem)" | |
last (neg index) -2.51% | |
middle (neg index) -1.88% | |
out of bound -1.11% | |
middle +0.05% | |
out of bound (neg index) +0.51% | |
first +1.55% | |
first (neg index) +1.67% | |
last +1.71% | |
## :"list_big (100000 elem)" | |
first -6.91% | |
middle -3.25% | |
out of bound (neg index) -1.60% | |
out of bound -1.52% | |
last -1.07% | |
last (neg index) -0.19% | |
first (neg index) +0.67% | |
middle (neg index) +0.96% | |
## :"list_empty (0 elem)" | |
out of bound -45.84% | |
out of bound (neg index) -45.50% | |
last (neg index) -43.66% | |
last -43.18% | |
middle (neg index) -6.54% | |
first (neg index) -5.56% | |
first -4.71% | |
middle -3.17% | |
## :"list_huge (600000 elem)" | |
last -1.72% | |
first (neg index) -0.31% | |
out of bound -0.27% | |
last (neg index) -- | |
middle +0.44% | |
out of bound (neg index) +2.33% | |
first +2.58% | |
middle (neg index) +2.65% | |
## :"list_single (1 elem)" | |
out of bound (neg index) -39.01% | |
out of bound -36.70% | |
last (neg index) -35.95% | |
middle +0.89% | |
first (neg index) +1.93% | |
middle (neg index) +1.96% | |
last +1.98% | |
first +3.27% | |
## :"map (1000 elem)" | |
first -0.91% | |
last +0.93% | |
middle +2.54% | |
last (neg index) +5.58% | |
first (neg index) +5.71% | |
middle (neg index) +5.73% | |
out of bound (neg index) +8.73% | |
out of bound +16.27% | |
## :"map_big (100000 elem)" | |
first (neg index) +2.38% | |
last (neg index) +3.57% | |
middle +4.21% | |
first +6.26% | |
middle (neg index) +6.83% | |
out of bound (neg index) +7.09% | |
last +10.15% | |
out of bound +17.70% | |
## :"map_empty (0 elem)" | |
middle -18.96% | |
middle (neg index) -8.30% | |
out of bound (neg index) -3.53% | |
first -3.34% | |
out of bound +0.49% | |
last +6.87% | |
first (neg index) +8.78% | |
last (neg index) +16.69% | |
## :"map_huge (600000 elem)" | |
out of bound (neg index) -11.18% | |
out of bound -9.69% | |
first -5.52% | |
middle (neg index) -2.74% | |
first (neg index) -2.33% | |
last (neg index) -2.22% | |
last +0.05% | |
middle +3.42% | |
## :"map_single (1 elem)" | |
middle -7.99% | |
last -6.34% | |
first (neg index) -4.94% | |
middle (neg index) -4.39% | |
first -2.85% | |
out of bound -0.96% | |
out of bound (neg index) +0.64% | |
last (neg index) +6.42% | |
## :"range (1000 elem)" | |
middle -3.06% | |
last (neg index) -3.01% | |
out of bound -1.96% | |
out of bound (neg index) -1.76% | |
first -1.15% | |
first (neg index) -0.91% | |
last -0.90% | |
middle (neg index) +0.88% | |
## :"range_big (100000 elem)" | |
first -2.28% | |
middle -2.04% | |
middle (neg index) -1.54% | |
first (neg index) -1.30% | |
last -1.25% | |
last (neg index) -1.19% | |
out of bound (neg index) -1.08% | |
out of bound -1.05% | |
## :"range_huge (600000 elem)" | |
out of bound -7.13% | |
out of bound (neg index) -5.85% | |
last -5.14% | |
first -2.83% | |
last (neg index) -1.24% | |
middle -0.36% | |
middle (neg index) -0.02% | |
first (neg index) +1.55% | |
## :"range_single (1 elem)" | |
out of bound -14.36% | |
middle (neg index) -7.50% | |
out of bound (neg index) -7.03% | |
last (neg index) -5.15% | |
middle -3.96% | |
first -3.05% | |
last -0.89% | |
first (neg index) +0.80% | |
## :"struct (1000 elem)" | |
out of bound -11.70% | |
out of bound (neg index) -10.25% | |
middle -9.44% | |
middle (neg index) -6.03% | |
first -5.06% | |
last (neg index) -4.91% | |
last +0.19% | |
first (neg index) +1.72% | |
## :"struct_big (100000 elem)" | |
last -9.54% | |
last (neg index) -3.86% | |
middle (neg index) -3.60% | |
middle -3.50% | |
first -0.78% | |
first (neg index) +1.09% | |
out of bound +1.18% | |
out of bound (neg index) +62.55% | |
## :"struct_empty (0 elem)" | |
first -7.12% | |
middle (neg index) -3.95% | |
first (neg index) +4.44% | |
middle +5.32% | |
last +12.77% | |
out of bound (neg index) +13.69% | |
last (neg index) +15.20% | |
out of bound +15.82% | |
## :"struct_huge (600000 elem)" | |
middle (neg index) -9.24% | |
last -5.99% | |
last (neg index) -1.70% | |
first (neg index) +2.66% | |
first +3.66% | |
out of bound +3.83% | |
middle +11.60% | |
out of bound (neg index) +11.88% | |
## :"struct_single (1 elem)" | |
first (neg index) -2.34% | |
middle -2.21% | |
first +0.56% | |
middle (neg index) +0.92% | |
last +1.05% | |
last (neg index) +6.03% | |
out of bound +13.88% | |
out of bound (neg index) +15.11% | |
Enum.fetch/2 - Elixir v1.4.0-dev (8b99214) | |
EnumFetch.RangeOptimized | |
Settings: | |
duration: 3.0 s | |
## :"list (1000 elem)" | |
[23:42:59] 1/152: first | |
[23:43:06] 2/152: first (neg index) | |
[23:43:15] 3/152: last | |
[23:43:22] 4/152: last (neg index) | |
[23:43:26] 5/152: middle | |
[23:43:32] 6/152: middle (neg index) | |
[23:43:38] 7/152: out of bound | |
[23:43:47] 8/152: out of bound (neg index) | |
## :"list_big (100000 elem)" | |
[23:43:56] 9/152: first | |
[23:44:03] 10/152: first (neg index) | |
[23:44:12] 11/152: last | |
[23:44:19] 12/152: last (neg index) | |
[23:44:22] 13/152: middle | |
[23:44:30] 14/152: middle (neg index) | |
[23:44:36] 15/152: out of bound | |
[23:44:45] 16/152: out of bound (neg index) | |
## :"list_empty (0 elem)" | |
[23:44:54] 17/152: first | |
[23:45:00] 18/152: first (neg index) | |
[23:45:07] 19/152: last | |
[23:45:15] 20/152: last (neg index) | |
[23:45:24] 21/152: middle | |
[23:45:30] 22/152: middle (neg index) | |
[23:45:36] 23/152: out of bound | |
[23:45:44] 24/152: out of bound (neg index) | |
## :"list_huge (600000 elem)" | |
[23:45:53] 25/152: first | |
[23:46:00] 26/152: first (neg index) | |
[23:46:07] 27/152: last | |
[23:46:14] 28/152: last (neg index) | |
[23:46:20] 29/152: middle | |
[23:46:23] 30/152: middle (neg index) | |
[23:46:32] 31/152: out of bound | |
[23:46:39] 32/152: out of bound (neg index) | |
## :"list_single (1 elem)" | |
[23:46:45] 33/152: first | |
[23:46:53] 34/152: first (neg index) | |
[23:47:01] 35/152: last | |
[23:47:09] 36/152: last (neg index) | |
[23:47:20] 37/152: middle | |
[23:47:28] 38/152: middle (neg index) | |
[23:47:36] 39/152: out of bound | |
[23:47:46] 40/152: out of bound (neg index) | |
## :"map (1000 elem)" | |
[23:47:56] 41/152: first | |
[23:48:04] 42/152: first (neg index) | |
[23:48:12] 43/152: last | |
[23:48:22] 44/152: last (neg index) | |
[23:48:31] 45/152: middle | |
[23:48:38] 46/152: middle (neg index) | |
[23:48:44] 47/152: out of bound | |
[23:49:04] 48/152: out of bound (neg index) | |
## :"map_big (100000 elem)" | |
[23:49:23] 49/152: first | |
[23:49:27] 50/152: first (neg index) | |
[23:49:30] 51/152: last | |
[23:49:36] 52/152: last (neg index) | |
[23:49:41] 53/152: middle | |
[23:49:48] 54/152: middle (neg index) | |
[23:49:55] 55/152: out of bound | |
[23:50:15] 56/152: out of bound (neg index) | |
## :"map_empty (0 elem)" | |
[23:50:35] 57/152: first | |
[23:50:51] 58/152: first (neg index) | |
[23:51:09] 59/152: last | |
[23:51:26] 60/152: last (neg index) | |
[23:51:44] 61/152: middle | |
[23:52:00] 62/152: middle (neg index) | |
[23:52:17] 63/152: out of bound | |
[23:52:35] 64/152: out of bound (neg index) | |
## :"map_huge (600000 elem)" | |
[23:52:52] 65/152: first | |
[23:53:04] 66/152: first (neg index) | |
[23:53:15] 67/152: last | |
[23:53:21] 68/152: last (neg index) | |
[23:53:28] 69/152: middle | |
[23:53:32] 70/152: middle (neg index) | |
[23:53:37] 71/152: out of bound | |
[23:54:02] 72/152: out of bound (neg index) | |
## :"map_single (1 elem)" | |
[23:54:27] 73/152: first | |
[23:54:32] 74/152: first (neg index) | |
[23:54:38] 75/152: last | |
[23:54:44] 76/152: last (neg index) | |
[23:54:51] 77/152: middle | |
[23:54:56] 78/152: middle (neg index) | |
[23:55:02] 79/152: out of bound | |
[23:55:20] 80/152: out of bound (neg index) | |
## :"range (1000 elem)" | |
[23:55:39] 81/152: first | |
[23:55:50] 82/152: first (neg index) | |
[23:56:07] 83/152: last | |
[23:56:19] 84/152: last (neg index) | |
[23:56:36] 85/152: middle | |
[23:56:48] 86/152: middle (neg index) | |
[23:57:05] 87/152: out of bound | |
[23:57:20] 88/152: out of bound (neg index) | |
## :"range_big (100000 elem)" | |
[23:57:35] 89/152: first | |
[23:57:47] 90/152: first (neg index) | |
[23:58:03] 91/152: last | |
[23:58:16] 92/152: last (neg index) | |
[23:58:32] 93/152: middle | |
[23:58:45] 94/152: middle (neg index) | |
[23:59:01] 95/152: out of bound | |
[23:59:16] 96/152: out of bound (neg index) | |
## :"range_huge (600000 elem)" | |
[23:59:32] 97/152: first | |
[23:59:44] 98/152: first (neg index) | |
[00:00:00] 99/152: last | |
[00:00:12] 100/152: last (neg index) | |
[00:00:29] 101/152: middle | |
[00:00:41] 102/152: middle (neg index) | |
[00:00:58] 103/152: out of bound | |
[00:01:13] 104/152: out of bound (neg index) | |
## :"range_single (1 elem)" | |
[00:01:28] 105/152: first | |
[00:01:38] 106/152: first (neg index) | |
[00:01:49] 107/152: last | |
[00:02:00] 108/152: last (neg index) | |
[00:02:12] 109/152: middle | |
[00:02:23] 110/152: middle (neg index) | |
[00:02:34] 111/152: out of bound | |
[00:02:45] 112/152: out of bound (neg index) | |
## :"struct (1000 elem)" | |
[00:02:57] 113/152: first | |
[00:03:10] 114/152: first (neg index) | |
[00:03:23] 115/152: last | |
[00:03:32] 116/152: last (neg index) | |
[00:03:41] 117/152: middle | |
[00:03:47] 118/152: middle (neg index) | |
[00:03:53] 119/152: out of bound | |
[00:04:14] 120/152: out of bound (neg index) | |
## :"struct_big (100000 elem)" | |
[00:04:35] 121/152: first | |
[00:04:43] 122/152: first (neg index) | |
[00:04:50] 123/152: last | |
[00:05:00] 124/152: last (neg index) | |
[00:05:10] 125/152: middle | |
[00:05:16] 126/152: middle (neg index) | |
[00:05:22] 127/152: out of bound | |
[00:05:43] 128/152: out of bound (neg index) | |
## :"struct_empty (0 elem)" | |
[00:06:04] 129/152: first | |
[00:06:24] 130/152: first (neg index) | |
[00:06:46] 131/152: last | |
[00:07:08] 132/152: last (neg index) | |
[00:07:29] 133/152: middle | |
[00:07:50] 134/152: middle (neg index) | |
[00:08:10] 135/152: out of bound | |
[00:08:32] 136/152: out of bound (neg index) | |
## :"struct_huge (600000 elem)" | |
[00:08:54] 137/152: first | |
[00:09:03] 138/152: first (neg index) | |
[00:09:12] 139/152: last | |
[00:09:18] 140/152: last (neg index) | |
[00:09:24] 141/152: middle | |
[00:09:28] 142/152: middle (neg index) | |
[00:09:32] 143/152: out of bound | |
[00:09:53] 144/152: out of bound (neg index) | |
## :"struct_single (1 elem)" | |
[00:10:14] 145/152: first | |
[00:10:22] 146/152: first (neg index) | |
[00:10:29] 147/152: last | |
[00:10:36] 148/152: last (neg index) | |
[00:10:44] 149/152: middle | |
[00:10:51] 150/152: middle (neg index) | |
[00:10:58] 151/152: out of bound | |
[00:11:20] 152/152: out of bound (neg index) | |
Finished in 1723.02 seconds | |
Enum.fetch/2 - Elixir v1.4.0-dev (8b99214) | |
EnumFetch.RangeOptimized | |
Settings: | |
duration: 3.0 s | |
## :"list (1000 elem)" | |
benchmark name iterations average time | |
first 100000000 0.07 µs/op | |
last (neg index) 1000000 4.11 µs/op | |
middle 1000000 5.34 µs/op | |
middle (neg index) 500000 9.36 µs/op | |
last 500000 10.86 µs/op | |
out of bound 500000 14.68 µs/op | |
first (neg index) 500000 14.69 µs/op | |
out of bound (neg index) 500000 14.72 µs/op | |
## :"list_big (100000 elem)" | |
benchmark name iterations average time | |
first 100000000 0.07 µs/op | |
last (neg index) 10000 347.38 µs/op | |
middle 10000 653.19 µs/op | |
middle (neg index) 5000 948.98 µs/op | |
last 5000 1098.88 µs/op | |
first (neg index) 5000 1424.04 µs/op | |
out of bound (neg index) 5000 1466.99 µs/op | |
out of bound 5000 1475.65 µs/op | |
## :"list_empty (0 elem)" | |
benchmark name iterations average time | |
first 100000000 0.06 µs/op | |
middle (neg index) 100000000 0.06 µs/op | |
middle 100000000 0.06 µs/op | |
first (neg index) 100000000 0.06 µs/op | |
last (neg index) 100000000 0.08 µs/op | |
out of bound (neg index) 100000000 0.08 µs/op | |
out of bound 100000000 0.08 µs/op | |
last 100000000 0.08 µs/op | |
## :"list_huge (600000 elem)" | |
benchmark name iterations average time | |
first 100000000 0.07 µs/op | |
middle 1000 3164.72 µs/op | |
last (neg index) 1000 4719.25 µs/op | |
last 1000 6400.34 µs/op | |
middle (neg index) 1000 7858.06 µs/op | |
out of bound (neg index) 500 11037.39 µs/op | |
out of bound 500 11109.95 µs/op | |
first (neg index) 500 11132.86 µs/op | |
## :"list_single (1 elem)" | |
benchmark name iterations average time | |
middle 100000000 0.07 µs/op | |
first 100000000 0.07 µs/op | |
first (neg index) 100000000 0.07 µs/op | |
middle (neg index) 100000000 0.07 µs/op | |
last 100000000 0.07 µs/op | |
out of bound (neg index) 100000000 0.09 µs/op | |
out of bound 100000000 0.09 µs/op | |
last (neg index) 100000000 0.10 µs/op | |
## :"map (1000 elem)" | |
benchmark name iterations average time | |
out of bound 100000000 0.18 µs/op | |
out of bound (neg index) 100000000 0.18 µs/op | |
first 200000 25.10 µs/op | |
first (neg index) 200000 25.18 µs/op | |
middle (neg index) 100000 57.51 µs/op | |
middle 100000 57.97 µs/op | |
last 100000 86.93 µs/op | |
last (neg index) 100000 87.22 µs/op | |
## :"map_big (100000 elem)" | |
benchmark name iterations average time | |
out of bound 100000000 0.18 µs/op | |
out of bound (neg index) 100000000 0.18 µs/op | |
first (neg index) 1000 3035.93 µs/op | |
first 1000 3054.08 µs/op | |
middle (neg index) 1000 6252.10 µs/op | |
middle 1000 6285.30 µs/op | |
last 500 9153.71 µs/op | |
last (neg index) 500 9348.79 µs/op | |
## :"map_empty (0 elem)" | |
benchmark name iterations average time | |
first 100000000 0.15 µs/op | |
middle (neg index) 100000000 0.15 µs/op | |
middle 100000000 0.15 µs/op | |
first (neg index) 100000000 0.16 µs/op | |
last (neg index) 100000000 0.16 µs/op | |
last 100000000 0.16 µs/op | |
out of bound (neg index) 100000000 0.16 µs/op | |
out of bound 100000000 0.16 µs/op | |
## :"map_huge (600000 elem)" | |
benchmark name iterations average time | |
out of bound 100000000 0.22 µs/op | |
out of bound (neg index) 100000000 0.22 µs/op | |
first 500 18400.28 µs/op | |
first (neg index) 500 18504.35 µs/op | |
middle 100 38574.12 µs/op | |
middle (neg index) 100 38704.60 µs/op | |
last 100 56486.23 µs/op | |
last (neg index) 100 57081.61 µs/op | |
## :"map_single (1 elem)" | |
benchmark name iterations average time | |
out of bound (neg index) 100000000 0.16 µs/op | |
out of bound 100000000 0.16 µs/op | |
first 10000000 0.51 µs/op | |
last 10000000 0.52 µs/op | |
middle 10000000 0.52 µs/op | |
first (neg index) 10000000 0.52 µs/op | |
middle (neg index) 10000000 0.53 µs/op | |
last (neg index) 10000000 0.60 µs/op | |
## :"range (1000 elem)" | |
benchmark name iterations average time | |
first 100000000 0.11 µs/op | |
last 100000000 0.11 µs/op | |
middle 100000000 0.11 µs/op | |
out of bound (neg index) 100000000 0.14 µs/op | |
out of bound 100000000 0.14 µs/op | |
first (neg index) 100000000 0.15 µs/op | |
middle (neg index) 100000000 0.15 µs/op | |
last (neg index) 100000000 0.15 µs/op | |
## :"range_big (100000 elem)" | |
benchmark name iterations average time | |
first 100000000 0.11 µs/op | |
last 100000000 0.11 µs/op | |
middle 100000000 0.11 µs/op | |
out of bound 100000000 0.14 µs/op | |
out of bound (neg index) 100000000 0.14 µs/op | |
last (neg index) 100000000 0.15 µs/op | |
middle (neg index) 100000000 0.15 µs/op | |
first (neg index) 100000000 0.15 µs/op | |
## :"range_huge (600000 elem)" | |
benchmark name iterations average time | |
first 100000000 0.11 µs/op | |
last 100000000 0.11 µs/op | |
middle 100000000 0.11 µs/op | |
out of bound 100000000 0.14 µs/op | |
out of bound (neg index) 100000000 0.14 µs/op | |
middle (neg index) 100000000 0.15 µs/op | |
last (neg index) 100000000 0.15 µs/op | |
first (neg index) 100000000 0.15 µs/op | |
## :"range_single (1 elem)" | |
benchmark name iterations average time | |
middle (neg index) 100000000 0.09 µs/op | |
first 100000000 0.10 µs/op | |
first (neg index) 100000000 0.10 µs/op | |
last 100000000 0.10 µs/op | |
middle 100000000 0.10 µs/op | |
out of bound (neg index) 100000000 0.11 µs/op | |
out of bound 100000000 0.11 µs/op | |
last (neg index) 100000000 0.11 µs/op | |
## :"struct (1000 elem)" | |
benchmark name iterations average time | |
out of bound (neg index) 100000000 0.19 µs/op | |
out of bound 100000000 0.19 µs/op | |
first 500000 20.84 µs/op | |
first (neg index) 500000 20.98 µs/op | |
middle 100000 51.20 µs/op | |
middle (neg index) 100000 51.50 µs/op | |
last 100000 84.06 µs/op | |
last (neg index) 100000 84.11 µs/op | |
## :"struct_big (100000 elem)" | |
benchmark name iterations average time | |
out of bound 100000000 0.19 µs/op | |
out of bound (neg index) 100000000 0.19 µs/op | |
first 2000 2449.68 µs/op | |
first (neg index) 2000 2461.34 µs/op | |
middle (neg index) 1000 5534.73 µs/op | |
middle 1000 5590.85 µs/op | |
last (neg index) 1000 8612.72 µs/op | |
last 1000 8670.67 µs/op | |
## :"struct_empty (0 elem)" | |
benchmark name iterations average time | |
first 100000000 0.18 µs/op | |
middle (neg index) 100000000 0.18 µs/op | |
middle 100000000 0.18 µs/op | |
first (neg index) 100000000 0.19 µs/op | |
last (neg index) 100000000 0.19 µs/op | |
out of bound (neg index) 100000000 0.20 µs/op | |
out of bound 100000000 0.20 µs/op | |
last 100000000 0.20 µs/op | |
## :"struct_huge (600000 elem)" | |
benchmark name iterations average time | |
out of bound (neg index) 100000000 0.19 µs/op | |
out of bound 100000000 0.19 µs/op | |
first (neg index) 500 14711.18 µs/op | |
first 500 14729.14 µs/op | |
middle (neg index) 100 33627.27 µs/op | |
middle 100 33685.23 µs/op | |
last 100 53375.65 µs/op | |
last (neg index) 100 53852.33 µs/op | |
## :"struct_single (1 elem)" | |
benchmark name iterations average time | |
out of bound (neg index) 100000000 0.19 µs/op | |
out of bound 100000000 0.20 µs/op | |
first (neg index) 10000000 0.65 µs/op | |
middle (neg index) 10000000 0.65 µs/op | |
middle 10000000 0.66 µs/op | |
first 10000000 0.66 µs/op | |
last 10000000 0.66 µs/op | |
last (neg index) 10000000 0.66 µs/op | |
bench/snapshots/2016-07-15_23-42-37.snapshot vs | |
bench/snapshots/2016-07-16_00-11-42.snapshot | |
## :"list (1000 elem)" | |
first -4.46% | |
first (neg index) -2.23% | |
out of bound -1.94% | |
middle -0.28% | |
middle (neg index) +0.06% | |
out of bound (neg index) +0.34% | |
last (neg index) +1.23% | |
last +2.00% | |
## :"list_big (100000 elem)" | |
first -4.51% | |
first (neg index) -0.66% | |
last (neg index) +0.42% | |
middle (neg index) +2.73% | |
out of bound (neg index) +3.78% | |
out of bound +3.79% | |
last +5.07% | |
middle +25.45% | |
## :"list_empty (0 elem)" | |
last (neg index) -7.97% | |
last -5.86% | |
out of bound (neg index) -5.00% | |
first (neg index) -4.60% | |
middle (neg index) -2.69% | |
out of bound -2.25% | |
first -2.14% | |
middle -1.14% | |
## :"list_huge (600000 elem)" | |
first -9.10% | |
middle -3.36% | |
middle (neg index) -2.87% | |
out of bound (neg index) -1.90% | |
last (neg index) -0.94% | |
last -0.05% | |
out of bound +0.19% | |
first (neg index) +0.79% | |
## :"list_single (1 elem)" | |
first -5.11% | |
out of bound -4.18% | |
last -4.02% | |
out of bound (neg index) -2.81% | |
first (neg index) -2.67% | |
middle (neg index) -2.33% | |
middle -2.19% | |
last (neg index) -1.45% | |
## :"map (1000 elem)" | |
out of bound -13.61% | |
out of bound (neg index) -7.51% | |
first (neg index) -6.17% | |
middle (neg index) -5.32% | |
middle -4.69% | |
last (neg index) -3.93% | |
first +0.11% | |
last +0.33% | |
## :"map_big (100000 elem)" | |
out of bound -13.30% | |
last -8.01% | |
middle (neg index) -5.03% | |
first -4.51% | |
out of bound (neg index) -4.35% | |
first (neg index) -2.71% | |
middle -2.07% | |
last (neg index) -0.20% | |
## :"map_empty (0 elem)" | |
last (neg index) -16.19% | |
first (neg index) -14.85% | |
middle -14.58% | |
first -5.99% | |
last -5.81% | |
middle (neg index) -0.17% | |
out of bound (neg index) +0.57% | |
out of bound +1.53% | |
## :"map_huge (600000 elem)" | |
middle -8.34% | |
last -4.29% | |
last (neg index) -3.36% | |
first (neg index) -1.46% | |
middle (neg index) -1.30% | |
out of bound -0.92% | |
out of bound (neg index) -0.29% | |
first +1.46% | |
## :"map_single (1 elem)" | |
first -7.38% | |
middle (neg index) -2.70% | |
first (neg index) -2.58% | |
last -1.44% | |
middle -1.35% | |
out of bound -1.31% | |
out of bound (neg index) -0.96% | |
last (neg index) -0.84% | |
## :"range (1000 elem)" | |
first +3.86% | |
middle +7.75% | |
last +10.31% | |
middle (neg index) +28.85% | |
last (neg index) +29.44% | |
first (neg index) +29.49% | |
out of bound +32.08% | |
out of bound (neg index) +32.32% | |
## :"range_big (100000 elem)" | |
first +3.84% | |
middle +7.44% | |
last +9.38% | |
middle (neg index) +25.34% | |
last (neg index) +28.52% | |
out of bound +30.28% | |
first (neg index) +31.30% | |
out of bound (neg index) +32.53% | |
## :"range_huge (600000 elem)" | |
first +4.70% | |
middle +6.96% | |
last +9.01% | |
first (neg index) +26.69% | |
middle (neg index) +27.41% | |
last (neg index) +30.25% | |
out of bound +31.54% | |
out of bound (neg index) +33.30% | |
## :"range_single (1 elem)" | |
last -0.21% | |
middle +4.28% | |
first (neg index) +4.39% | |
middle (neg index) +4.56% | |
first +5.01% | |
last (neg index) +14.02% | |
out of bound (neg index) +14.18% | |
out of bound +14.56% | |
## :"struct (1000 elem)" | |
last -5.13% | |
first (neg index) -4.63% | |
out of bound -1.01% | |
first -0.35% | |
middle -0.22% | |
middle (neg index) -0.02% | |
out of bound (neg index) +0.08% | |
last (neg index) +1.44% | |
## :"struct_big (100000 elem)" | |
out of bound (neg index) -45.82% | |
out of bound -14.92% | |
first (neg index) -0.98% | |
middle (neg index) -0.91% | |
last (neg index) -0.84% | |
first +0.10% | |
last +1.52% | |
middle +1.89% | |
## :"struct_empty (0 elem)" | |
last (neg index) -14.81% | |
first (neg index) -14.16% | |
first -13.80% | |
middle -13.27% | |
out of bound -13.23% | |
out of bound (neg index) -12.50% | |
last -12.47% | |
middle (neg index) -5.19% | |
## :"struct_huge (600000 elem)" | |
out of bound (neg index) -13.70% | |
middle -10.31% | |
first -5.82% | |
out of bound -5.06% | |
first (neg index) -4.85% | |
last (neg index) -3.49% | |
last -2.58% | |
middle (neg index) -0.09% | |
## :"struct_single (1 elem)" | |
out of bound (neg index) -12.81% | |
out of bound -12.64% | |
last (neg index) -5.36% | |
middle -3.69% | |
first -3.32% | |
middle (neg index) -2.99% | |
last -2.93% | |
first (neg index) -2.73% | |
$ mix bench.cmp bench/snapshots/2016-07-15_23-13-57.snapshot bench/snapshots/2016-07-16_00-11-42.snapshot -d percent | |
bench/snapshots/2016-07-15_23-13-57.snapshot vs | |
bench/snapshots/2016-07-16_00-11-42.snapshot | |
## :"list (1000 elem)" | |
out of bound -3.03% | |
first -2.99% | |
middle (neg index) -1.82% | |
last (neg index) -1.30% | |
first (neg index) -0.59% | |
middle -0.23% | |
out of bound (neg index) +0.86% | |
last +3.75% | |
## :"list_big (100000 elem)" | |
first -11.10% | |
first (neg index) +0.01% | |
last (neg index) +0.22% | |
out of bound (neg index) +2.12% | |
out of bound +2.21% | |
middle (neg index) +3.72% | |
last +3.95% | |
middle +21.37% | |
## :"list_empty (0 elem)" | |
out of bound (neg index) -48.23% | |
last (neg index) -48.15% | |
out of bound -47.05% | |
last -46.51% | |
first (neg index) -9.90% | |
middle (neg index) -9.05% | |
first -6.75% | |
middle -4.28% | |
## :"list_huge (600000 elem)" | |
first -6.76% | |
middle -2.94% | |
last -1.76% | |
last (neg index) -0.94% | |
middle (neg index) -0.30% | |
out of bound -0.07% | |
out of bound (neg index) +0.39% | |
first (neg index) +0.48% | |
## :"list_single (1 elem)" | |
out of bound (neg index) -40.72% | |
out of bound -39.35% | |
last (neg index) -36.88% | |
last -2.12% | |
first -2.01% | |
middle -1.32% | |
first (neg index) -0.79% | |
middle (neg index) -0.41% | |
## :"map (1000 elem)" | |
middle -2.27% | |
first (neg index) -0.82% | |
first -0.81% | |
middle (neg index) +0.11% | |
out of bound +0.44% | |
out of bound (neg index) +0.56% | |
last +1.26% | |
last (neg index) +1.42% | |
## :"map_big (100000 elem)" | |
first (neg index) -0.39% | |
last +1.32% | |
middle (neg index) +1.45% | |
first +1.46% | |
middle +2.04% | |
out of bound +2.05% | |
out of bound (neg index) +2.43% | |
last (neg index) +3.36% | |
## :"map_empty (0 elem)" | |
middle -30.78% | |
first -9.13% | |
middle (neg index) -8.45% | |
first (neg index) -7.37% | |
out of bound (neg index) -2.98% | |
last (neg index) -2.20% | |
last +0.66% | |
out of bound +2.03% | |
## :"map_huge (600000 elem)" | |
out of bound (neg index) -11.45% | |
out of bound -10.51% | |
last (neg index) -5.51% | |
middle -5.21% | |
last -4.25% | |
first -4.14% | |
middle (neg index) -4.01% | |
first (neg index) -3.76% | |
## :"map_single (1 elem)" | |
first -10.02% | |
middle -9.23% | |
last -7.68% | |
first (neg index) -7.39% | |
middle (neg index) -6.98% | |
out of bound -2.26% | |
out of bound (neg index) -0.32% | |
last (neg index) +5.53% | |
## :"range (1000 elem)" | |
first +2.67% | |
middle +4.44% | |
last +9.32% | |
last (neg index) +25.55% | |
first (neg index) +28.32% | |
out of bound +29.49% | |
out of bound (neg index) +29.99% | |
middle (neg index) +29.99% | |
## :"range_big (100000 elem)" | |
first +1.47% | |
middle +5.25% | |
last +8.01% | |
middle (neg index) +23.41% | |
last (neg index) +26.99% | |
out of bound +28.92% | |
first (neg index) +29.59% | |
out of bound (neg index) +31.11% | |
## :"range_huge (600000 elem)" | |
first +1.73% | |
last +3.40% | |
middle +6.57% | |
out of bound +22.16% | |
out of bound (neg index) +25.50% | |
middle (neg index) +27.38% | |
last (neg index) +28.63% | |
first (neg index) +28.65% | |
## :"range_single (1 elem)" | |
middle (neg index) -3.28% | |
out of bound -1.89% | |
last -1.11% | |
middle +0.16% | |
first +1.81% | |
first (neg index) +5.23% | |
out of bound (neg index) +6.15% | |
last (neg index) +8.16% | |
## :"struct (1000 elem)" | |
out of bound -12.59% | |
out of bound (neg index) -10.18% | |
middle -9.64% | |
middle (neg index) -6.05% | |
first -5.40% | |
last -4.95% | |
last (neg index) -3.54% | |
first (neg index) -2.99% | |
## :"struct_big (100000 elem)" | |
out of bound -13.92% | |
out of bound (neg index) -11.93% | |
last -8.17% | |
last (neg index) -4.67% | |
middle (neg index) -4.48% | |
middle -1.68% | |
first -0.68% | |
first (neg index) +0.10% | |
## :"struct_empty (0 elem)" | |
first -19.94% | |
first (neg index) -10.35% | |
middle (neg index) -8.93% | |
middle -8.66% | |
last (neg index) -1.86% | |
last -1.29% | |
out of bound (neg index) -0.52% | |
out of bound +0.50% | |
## :"struct_huge (600000 elem)" | |
middle (neg index) -9.32% | |
last -8.41% | |
last (neg index) -5.13% | |
out of bound (neg index) -3.45% | |
first -2.37% | |
first (neg index) -2.32% | |
out of bound -1.43% | |
middle +0.09% | |
## :"struct_single (1 elem)" | |
middle -5.82% | |
first (neg index) -5.00% | |
first -2.78% | |
middle (neg index) -2.10% | |
last -1.91% | |
out of bound -0.52% | |
last (neg index) +0.35% | |
out of bound (neg index) +0.36% |
This file contains 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
defmodule Data do | |
@terms [ | |
:range, :range_single, :range_big, :range_huge, | |
:list, :list_empty, :list_single, :list_big, :list_huge, | |
:map, :map_empty, :map_single, :map_big, :map_huge, | |
:struct, :struct_empty, :struct_single, :struct_big, :struct_huge, | |
# :string, | |
] | |
@range -499..500 | |
@range_single 0..0 | |
@range_big -49_999..50_000 | |
@range_huge -299_999..300_000 | |
@list @range |> Enum.to_list | |
@list_empty [] | |
@list_single [1] | |
@list_big @range_big |> Enum.to_list | |
@list_huge @range_huge |> Enum.to_list | |
@map @list |> Enum.map(fn(v) -> {v, v} end) |> Enum.into(%{}) | |
@map_empty %{} | |
@map_single %{1 => 1} | |
@map_big @list_big |> Enum.map(fn(v) -> {v, v} end) |> Enum.into(%{}) | |
@map_huge @list_huge |> Enum.map(fn(v) -> {v, v} end) |> Enum.into(%{}) | |
@struct MapSet.new(@list) | |
@struct_empty MapSet.new | |
@struct_single MapSet.new(@list_single) | |
@struct_big MapSet.new(@list_big) | |
@struct_huge MapSet.new(@list_huge) | |
# @string Stream.repeatedly(fn -> Enum.random(?A..?z) end) |> Enum.take(10000) |> to_string | |
def get_module, | |
do: [System.get_env["MODULE"]] |> Module.concat | |
def terms, | |
do: @terms | |
def get_term(:range), | |
do: @range | |
def get_term(:range_single), | |
do: @range_single | |
def get_term(:range_big), | |
do: @range_big | |
def get_term(:range_huge), | |
do: @range_huge | |
def get_term(:list), | |
do: @list | |
def get_term(:list_empty), | |
do: @list_empty | |
def get_term(:list_single), | |
do: @list_single | |
def get_term(:list_big), | |
do: @list_big | |
def get_term(:list_huge), | |
do: @list_huge | |
def get_term(:map), | |
do: @map | |
def get_term(:map_empty), | |
do: @map_empty | |
def get_term(:map_single), | |
do: @map_single | |
def get_term(:map_big), | |
do: @map_big | |
def get_term(:map_huge), | |
do: @map_huge | |
def get_term(:struct), | |
do: @struct | |
def get_term(:struct_empty), | |
do: @struct_empty | |
def get_term(:struct_single), | |
do: @struct_single | |
def get_term(:struct_big), | |
do: @struct_big | |
def get_term(:struct_huge), | |
do: @struct_huge | |
# def get_term(:string), | |
# do: @string | |
end | |
defmodule EnumFetchBench do | |
import Data | |
require EnumFetch.Original | |
require EnumFetch.Master | |
require EnumFetch.RangeOptimized | |
use Benchfella | |
IO.puts "Enum.fetch/2 - Elixir v#{System.build_info[:build]}" | |
IO.puts System.get_env["MODULE"] | |
for term_name <- terms() do | |
count = | |
try do | |
Enum.count(get_term(term_name)) | |
rescue | |
_ -> | |
nil | |
catch | |
x -> | |
x | |
end | |
defmodule :"#{term_name} (#{count} elem)" do | |
use Benchfella | |
@term_name term_name | |
@count count | |
@last @count - 1 | |
@middle @last |> div(2) | |
@middle_neg abs(@middle) * -1 | |
@past @count + 1_000 | |
@past_neg abs(@count + 1_000) * -1 | |
bench "first", [module: get_module(), term: get_term(@term_name)] do | |
module.fetch(term, 0) | |
end | |
bench "first (neg index)", [module: get_module(), term: get_term(@term_name)] do | |
module.fetch(term, -(@last)) | |
end | |
bench "middle", [module: get_module(), term: get_term(@term_name)] do | |
module.fetch(term, @middle) | |
end | |
bench "middle (neg index)", [module: get_module(), term: get_term(@term_name)] do | |
module.fetch(term, @middle_neg) | |
end | |
bench "last", [module: get_module(), term: get_term(@term_name)] do | |
module.fetch(term, @last) | |
end | |
bench "last (neg index)", [module: get_module(), term: get_term(@term_name)] do | |
module.fetch(term, -1) | |
end | |
bench "out of bound", [module: get_module(), term: get_term(@term_name)] do | |
module.fetch(term, @past_neg) | |
end | |
bench "out of bound (neg index)", [module: get_module(), term: get_term(@term_name)] do | |
module.fetch(term, @past_neg) | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment