Size: a a a

2020 May 17

V

V in pro.elixir
Смотри на вещи позитивно - у эликсира есть потенциал стать в следующих версиях быстрее ;)
источник

Е

Евгений in pro.elixir
V
Смотри на вещи позитивно - у эликсира есть потенциал стать в следующих версиях быстрее ;)
:)) если обувь жмет, не расстраивайся, представь как тебе будет хорошо, когда ты ее снимешь :))
источник

Е

Евгений in pro.elixir
Пойду побенчу, если будет смысл сделаю PR, а бенч будет доказательством :)
источник

V

V in pro.elixir
можешь ещё в слаке с чуваками обсудить, они там живые и разговорчивые
источник

Е

Евгений in pro.elixir
V
можешь ещё в слаке с чуваками обсудить, они там живые и разговорчивые
Да что тут обсуждать? Если реально будет быстрее, то думаю никто, включая Валима возражать не будет
источник

ŹR

Źmićer Rubinštejn in pro.elixir
defmodule IterReduce do
 def iter_reduce(map, initial_acc, fun) do
   do_iter_reduce(:maps.iterator(map), initial_acc, fun)
 end

 def do_iter_reduce(iter, acc, fun) do
   case :maps.next(iter) do
     :none -> acc
     {k, v, next_iter} -> do_iter_reduce(next_iter, fun.({k, v}, acc), fun)
   end
 end
end

inputs = %{
 "Small map"  => Enum.map(1..10,      fn el -> {to_string(el), el} end) |> Enum.into(%{}),
 "Medium map" => Enum.map(1..1000,    fn el -> {to_string(el), el} end) |> Enum.into(%{}),
 "Large map"  => Enum.map(1..1000000, fn el -> {to_string(el), el} end) |> Enum.into(%{})
}

Benchee.run(%{
 "Elixir shit" => fn map ->            Enum.reduce(map, {"", 0}, fn {k, v}, {acc_k, acc_v} -> {acc_k <> k, acc_v + v} end) end,
 "Iterators" =>   fn  map-> IterReduce.iter_reduce(map, {"", 0}, fn {k, v}, {acc_k, acc_v} -> {acc_k <> k, acc_v + v} end) end,
}, inputs: inputs)


Results:

`
Operating System: macOS
CPU Information: Intel(R) Core(TM) i7-8557U CPU @ 1.70GHz
Number of Available Cores: 8
Available memory: 16 GB
Elixir 1.9.4
Erlang 22.1

Benchmark suite executing with the following configuration:
warmup: 2 s
time: 5 s
memory time: 0 ns
parallel: 1
inputs: none specified
Estimated total run time: 42 s

Benchmarking Lg: Elixir shit...
Benchmarking Lg: Iterators...
Benchmarking Md: Elixir shit...
Benchmarking Md: Iterators...
Benchmarking Sm: Elixir shit...
Benchmarking Sm: Iterators...

Name                      ips        average  deviation         median         99th %
Sm: Iterators        585.08 K        1.71 μs  ±1736.83%        0.90 μs        2.90 μs
Sm: Elixir shit      485.71 K        2.06 μs  ±1265.29%        1.90 μs        3.90 μs
Md: Elixir shit        1.05 K      948.42 μs    ±41.85%      853.90 μs     1861.86 μs
Md: Iterators          0.84 K     1191.63 μs    ±30.73%     1067.90 μs     2352.18 μs
Lg: Iterators       0.00054 K  1846101.12 μs    ±34.77%  1636249.48 μs  2743530.71 μs
Lg: Elixir shit     0.00049 K  2030950.57 μs    ±10.21%  1921483.17 μs  2270112.40 μs

Comparison:
Sm: Iterators        585.08 K
Sm: Elixir shit      485.71 K - 1.20x slower +0.35 μs
Md: Elixir shit        1.05 K - 554.90x slower +946.71 μs
Md: Iterators          0.84 K - 697.19x slower +1189.92 μs
Lg: Iterators       0.00054 K - 1080111.45x slower +1846099.41 μs
Lg: Elixir shit     0.00049 K - 1188262.62x slower +2030948.86 μs
virviil@virviil bencher % mix run maps.exs
** (SyntaxError) maps.exs:20: syntax error before: "Medium map"
   (elixir) lib/code.ex:813: Code.require_file/2
   (mix) lib/mix/tasks/run.ex:145: Mix.Tasks.Run.run/5
   (mix) lib/mix/tasks/run.ex:85: Mix.Tasks.Run.run/1
   (mix) lib/mix/task.ex:331: Mix.Task.run_task/3
   (mix) lib/mix/cli.ex:79: Mix.CLI.run_task/2
virviil@virviil bencher % mix run maps.exs
** (SyntaxError) maps.exs:16: syntax error before: ','
   (elixir) lib/code.ex:813: Code.require_file/2
   (mix) lib/mix/tasks/run.ex:145: Mix.Tasks.Run.run/5
   (mix) lib/mix/tasks/run.ex:85: Mix.Tasks.Run.run/1
   (mix) lib/mix/task.ex:331: Mix.Task.run_task/3
   (mix) lib/mix/cli.ex:79: Mix.CLI.run_task/2
virviil@virviil bencher % mix run maps.exs
** (CompileError) maps.exs:1: undefined function efmodule/2
   (elixir) lib/code.ex:813: Code.require_file/2
virviil@virviil bencher % mix run maps.exs
Operating System: macOS
CPU Information: Intel(R) Core(TM) i7-8557U CPU @ 1.70GHz
Number of Available Cores: 8
Available memory: 16 GB
Elixir 1.9.4
Erlang 22.1

Benchmark suite executing with the following configuration:
warmup: 2 s
time: 5 s
memory time: 0 ns
parallel: 1
inputs: Large map, Medium map, Small map
Estimated total run time: 42 s

Benchmarking Elixir shit with input Large map...
Benchmarking Elixir shit with input Medium map...
Benchmarking Elixir shit with input Small map...
Benchmarking Iterators with input Large map...
Benchmarking Iterators with input Medium map...
Benchmarking Iterators with input Small map...

##### With input Large map #####
Name                  ips        average  deviation         median         99th %
источник

ŹR

Źmićer Rubinštejn in pro.elixir
Iterators            2.96      337.85 ms    ±30.14%      328.45 ms      510.15 ms
Elixir shit          1.78      561.27 ms    ±20.00%      527.48 ms      729.99 ms

Comparison:
Iterators            2.96
Elixir shit          1.78 - 1.66x slower +223.42 ms

##### With input Medium map #####
Name                  ips        average  deviation         median         99th %
Iterators        244.33 K        4.09 μs  ±6081.40%           0 μs       57.00 μs
Elixir shit       53.70 K       18.62 μs  ±1386.46%        1.00 μs      152.12 μs

Comparison:
Iterators        244.33 K
Elixir shit       53.70 K - 4.55x slower +14.53 μs

##### With input Small map #####
Name                  ips        average  deviation         median         99th %
Iterators          3.59 M      278.29 ns ±18007.85%           0 ns           0 ns
Elixir shit        3.19 M      313.54 ns ±19610.93%           0 ns           0 ns

Comparison:
Iterators          3.59 M
Elixir shit        3.19 M - 1.13x slower +35.26 ns
`


Если я нигде не проебался, то на итераторах быстрее для любых размеров мап
источник

ŹR

Źmićer Rubinštejn in pro.elixir
Фишка правда в том, что при передаче мапы вызывается другая функция:

https://github.com/elixir-lang/elixir/blob/c592d1300d3dba34bf8005cb9e124c9004ac45ea/lib/elixir/lib/enum.ex#L2178
источник

ŹR

Źmićer Rubinštejn in pro.elixir
А вот почему :maps.fold медленнее чем реализация с итератором - я не знаю
источник

ŹR

Źmićer Rubinštejn in pro.elixir
источник

ŹR

Źmićer Rubinštejn in pro.elixir
Ответ - никто
источник

ŹR

Źmićer Rubinštejn in pro.elixir
И все равно, сказать без бенчей что итератор быстрее чем запихать все в лист сперва - невозможно
источник

ŹR

Źmićer Rubinštejn in pro.elixir
Вот и пойми теперь этот бенч...

https://github.com/erlang/otp/blob/master/lib/stdlib/src/maps.erl#L230
источник

ŹR

Źmićer Rubinštejn in pro.elixir
Видимо всетки я где-то проебался
источник

ŹR

Źmićer Rubinštejn in pro.elixir
Но конечно то, что я за 5 минут в бенче пишу код качества ОТП меня радует Ж))
источник

V

V in pro.elixir
Źmićer Rubinštejn
Ответ - никто
Можно вызывать Enumerable.reduce(map, acc, fn), но он упадёт.
источник

V

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

ŹR

Źmićer Rubinštejn in pro.elixir
```
Enumerable.reduce(map, {:cont, acc}, fn)
```
источник

ŹR

Źmićer Rubinštejn in pro.elixir
Вот так надо
источник

V

V in pro.elixir
Один хер не работает
источник