Size: a a a

2020 May 17

LL

Lama Lover in pro.elixir
Simon Khaskelberg
Т.е разница небольшая, но все же есть
Ну, в маленькой мапе слишком большая девиация, поэтому к этому результату нужно оноситься особенно скептически
Во всех остальных практически одинаковые медианы
источник

SK

Simon Khaskelberg in pro.elixir
Получается, что прирост по памяти и времени происходит из-за того что передаем лябду в :maps.fold в Enum.reduce
источник

V

V in pro.elixir
Simon Khaskelberg
Как по мне самое интересное это разница в памяти. Enum.reduce стабильно в 1.75 раза памяти ест больше чем :maps.fold
А в моих тестах разницы в использовании памяти нет никакой. https://t.me/proelixir/152697
источник

SK

Simon Khaskelberg in pro.elixir
V
А в моих тестах разницы в использовании памяти нет никакой. https://t.me/proelixir/152697
Странно. Интересно, что я тогда не правильно делаю
источник

V

V in pro.elixir
система во время тестов свопиться не начинает?
источник

SK

Simon Khaskelberg in pro.elixir
Нет
источник

SK

Simon Khaskelberg in pro.elixir
V
А в моих тестах разницы в использовании памяти нет никакой. https://t.me/proelixir/152697
А ты код своих тестов можешь показать?
источник
2020 May 18

V

V in pro.elixir
Simon Khaskelberg
А ты код своих тестов можешь показать?
источник

V

V in pro.elixir
Я отдельно тестировал маленькие и отдельно большие мапы. Параметры для Benchee.run были warmup 10, time 30 для больших мап, warmup 5, time 5 для маленьких. parallel пробовал разные - 1, 2, 8.
источник

SK

Simon Khaskelberg in pro.elixir
V
Я отдельно тестировал маленькие и отдельно большие мапы. Параметры для Benchee.run были warmup 10, time 30 для больших мап, warmup 5, time 5 для маленьких. parallel пробовал разные - 1, 2, 8.
":maps.fold" => fn map -> :maps.fold(fn k, v, acc -> fold.({k, v}, acc) end, {"", 0}, map) end
источник

SK

Simon Khaskelberg in pro.elixir
Если вот так вызывать замыкание через  точку, то я тоже  получаю одинаковый результат с Enum,reduce (Оно в reduce так и реализовано)
источник

SK

Simon Khaskelberg in pro.elixir
А вот если подставить функцию напрямую, то у меня получается значительная разница в памяти
источник

V

V in pro.elixir
покажи как
источник

SK

Simon Khaskelberg in pro.elixir
Вот как-то так :maps.fold(fn k, v, {acc_k, acc_v} -> {acc_k <> k, acc_v + v} end, {"", 0}, map)
источник

V

V in pro.elixir
т.е. убрать обёртку fn map -> ... end?
источник

SK

Simon Khaskelberg in pro.elixir
Если убрать вызов fold.({k, v}, acc)
источник

Е

Евгений in pro.elixir
Убирать вызов бессмысленно. Это же и есть смысл reduce. Какая-то бесполезная синтетика получится.
источник

V

V in pro.elixir
Если совместить твой вариант с оптимизированным итератором, то получится
defmodule IterReduce do
 def iter_reduce_superoptimized(map) do
   do_iter_reduce_superoptimized(:maps.iterator(map), "", 0)
 end

 defp do_iter_reduce_superoptimized(iter, acc_k, acc_v) do
   case :maps.next(iter) do
     :none -> {acc_k, acc_v}
     {k, v, next_iter} -> do_iter_reduce_superoptimized(next_iter, acc_k <> k, acc_v + v)
   end
 end
end

Benchee.run(%{
 "IterReduce.iter_reduce_superoptimized" => fn map -> IterReduce.iter_reduce_superoptimized(map) end,
})

С примерно такими результатами:
Comparison: 
IterReduce.iter_reduce_superoptimized        
IterReduce.iter_reduce_optimized             1.29x slower
:maps.fold unwrapped                         1.29x slower
IterReduce.iter_reduce                       1.39x slower
:maps.fold                                   1.59x slower
Enum.reduce                                  1.60x slower
источник

SK

Simon Khaskelberg in pro.elixir
А по памяти?
источник

Е

Евгений in pro.elixir
Сделать reduce на макросах, чтобы он тело функции сразу пихал вместо вызова :D
источник