Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@eksperimental
Last active July 16, 2016 02:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eksperimental/3f9c58a5b27fa9ff05abcd1df4678b1a to your computer and use it in GitHub Desktop.
Save eksperimental/3f9c58a5b27fa9ff05abcd1df4678b1a to your computer and use it in GitHub Desktop.
Enum.fetch/2 Optimizations
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
$ 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%
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