Е
@pham_nuwen FYI
Size: a a a
Е
Е
Е
reduce_while
, который вроде как использует уже протоколы, ожидал большой разницы, но на удивление разница не так уж и велика:iter 18.67
elixir 13.08 - 1.43x slower +22.88 ms
Е
Е
Е
a
Enum.reduce_while
для мап использует как раз протокольный Enumerable.reduce
LL
Е
Enum.reduce
для мап и списков специализирован и не обращается к протоколу Enumerable для мап и списков.a
a
LL
SK
a
Enumerable
для Map
и как-то жестко прихуел:Enumerable.List.reduce(:maps.to_list(map), acc, fun)
LL
SK
inputs = %{
"100_000 elements" => Enum.map(1..100_000, fn el -> {to_string(el), el} end) |> Enum.into(%{}),
"1_000_000 elements" =>
Enum.map(1..1_000_000, fn el -> {to_string(el), el} end) |> Enum.into(%{}),
"10_000_000 elements" =>
Enum.map(1..10_000_000, fn el -> {to_string(el), el} end) |> Enum.into(%{})
}
Benchee.run(
%{
"Enumerable.reduce" => fn map ->
Enumerable.reduce(map, {:cont, 0}, fn {_, v}, acc -> {:cont, acc + v} end)
end,
"Enum.reduce" => fn map ->
Enum.reduce(map, 0, fn {_, v}, acc -> acc + v end)
end,
":maps.fold" => fn map ->
:maps.fold(fn _k, v, acc -> acc + v end, 0, map)
end
},
inputs: inputs,
warmup: 10,
time: 20,
memory_time: 5
)
LL
inputs = %{
"100_000 elements" => Enum.map(1..100_000, fn el -> {to_string(el), el} end) |> Enum.into(%{}),
"1_000_000 elements" =>
Enum.map(1..1_000_000, fn el -> {to_string(el), el} end) |> Enum.into(%{}),
"10_000_000 elements" =>
Enum.map(1..10_000_000, fn el -> {to_string(el), el} end) |> Enum.into(%{})
}
Benchee.run(
%{
"Enumerable.reduce" => fn map ->
Enumerable.reduce(map, {:cont, 0}, fn {_, v}, acc -> {:cont, acc + v} end)
end,
"Enum.reduce" => fn map ->
Enum.reduce(map, 0, fn {_, v}, acc -> acc + v end)
end,
":maps.fold" => fn map ->
:maps.fold(fn _k, v, acc -> acc + v end, 0, map)
end
},
inputs: inputs,
warmup: 10,
time: 20,
memory_time: 5
)
SK
##### With input 100_000 elements #####
Name ips average deviation median 99th %
:maps.fold 208.10 4.81 ms ±94.18% 4.49 ms 8.86 ms
Enumerable.reduce 180.48 5.54 ms ±139.45% 5.20 ms 10.77 ms
Enum.reduce 156.41 6.39 ms ±82.14% 6.35 ms 9.85 ms
Comparison:
:maps.fold 208.10
Enumerable.reduce 180.48 - 1.15x slower +0.74 ms
Enum.reduce 156.41 - 1.33x slower +1.59 ms
Memory usage statistics:
Name Memory usage
:maps.fold 3.00 MB
Enumerable.reduce 6.07 MB - 2.02x memory usage +3.07 MB
Enum.reduce 5.31 MB - 1.77x memory usage +2.31 MB
**All measurements for memory usage were the same**
##### With input 10_000_000 elements #####
Name ips average deviation median 99th %
:maps.fold 2.23 448.57 ms ±19.78% 438.49 ms 998.63 ms
Enumerable.reduce 1.74 575.91 ms ±33.01% 552.81 ms 1530.11 ms
Enum.reduce 1.65 604.37 ms ±17.60% 588.14 ms 1135.32 ms
Comparison:
:maps.fold 2.23
Enumerable.reduce 1.74 - 1.28x slower +127.33 ms
Enum.reduce 1.65 - 1.35x slower +155.79 ms
Memory usage statistics:
Name Memory usage
:maps.fold 305.35 MB
Enumerable.reduce 610.89 MB - 2.00x memory usage +305.54 MB
Enum.reduce 534.26 MB - 1.75x memory usage +228.92 MB
**All measurements for memory usage were the same**
##### With input 1_000_000 elements #####
Name ips average deviation median 99th %
:maps.fold 20.69 48.32 ms ±34.23% 47.37 ms 64.95 ms
Enumerable.reduce 15.72 63.60 ms ±33.28% 62.84 ms 80.84 ms
Enum.reduce 15.70 63.71 ms ±29.81% 63.63 ms 70.67 ms
Comparison:
:maps.fold 20.69
Enumerable.reduce 15.72 - 1.32x slower +15.28 ms
Enum.reduce 15.70 - 1.32x slower +15.39 ms
Memory usage statistics:
Name Memory usage
:maps.fold 30.45 MB
Enumerable.reduce 60.98 MB - 2.00x memory usage +30.53 MB
Enum.reduce 53.38 MB - 1.75x memory usage +22.93 MB
**All measurements for memory usage were the same**
SK
SK