Sorry. Would putting them in a test case be better practice? If not, do you mind telling me of the correct way which would produce the most indicative results?
On Thursday, December 30, 2021 at 6:24:08 PM UTC-5 José Valim wrote: > Don’t benchmark in the shell. Code in the shell is evaluated and not > compiled. > > On Fri, Dec 31, 2021 at 00:14 Paul Alexander <paul.aj...@gmail.com> wrote: > >> Thanks for offering your opinion, José. I very much understand where >> you're coming in regards to using Enum.reduce/3 for such an operation, but >> I have found it to cause a fair amount of needless overhead especially when >> there are other operations going on and the updating should be the most >> trivial. Since you brought up the efficiency tradeoffs, I've put together a >> few simple benchmarks below for the Map functions where the results are >> from averaging 10k iterations. As you can see the performance improvement >> is quite drastic, with both *_many functions being 130%+ . >> >> iex> map >> >> %{a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10} >> >> iex> kv >> >> [a: 11, d: 22, g: 33, j: 44] >> >> iex> keys >> >> [:a, :d, :g, :j] >> >> iex(32)> Benchmark.measure(10_000, "reduce + replace!", fn -> >> Enum.reduce(kv, map, fn {k, v}, acc -> Map.replace!(acc, k, v) end) end) >> >> reduce + replace! avg: 18.2396 >> >> iex(33)> Benchmark.measure(10_000, "replace_many", fn -> >> Map.replace_many(map, kv) end) >> >> replace_many avg: 1.0979 >> >> iex(34)> Benchmark.measure(10_000, "reduce + update!", fn -> >> Enum.reduce(keys, map, fn k, acc -> Map.update!(acc, k, &(&1*2)) end) end) >> >> reduce + update! avg: 48.284 >> >> iex(35)> Benchmark.measure(10_000, "update_many", fn -> >> Map.update_many(map, keys, &(&1*2)) end) >> >> update_many avg: 9.8719 >> On Thursday, December 30, 2021 at 5:13:10 PM UTC-5 José Valim wrote: >> >>> Hi Paul, >>> >>> Thanks for the proposal. My personal take is that a Enum.reduce/3 + the >>> relevant Map operation should be the way to go, because this can easily >>> lead to a combination of replace_many, update_many, put_new_many, etc. >>> Especially because the many operations likely wouldn't be any more >>> efficient than the Enum.reduce/3 call. >>> >>> >>> On Thu, Dec 30, 2021 at 10:42 PM Paul Alexander <paul.aj...@gmail.com> >>> wrote: >>> >>>> Hi everyone, >>>> >>>> I would like to discuss the possibility of adding two new functions to >>>> each of the Map and Keyword modules; replace_many/2 and update_many/3. >>>> Their purpose is to update maps and keyword lists providing either a >>>> keyword list of the key-value pairs which need to updated, or a list of >>>> keys and a function which operates on the existing values of those keys. >>>> >>>> Far too often I find myself needing to call replace!/3 or update!/3 >>>> several times from within a pipeline, or even needing to use a >>>> for-comprehension or Enum.reduce/3 to update a map in "one shot", when it >>>> feels like there should be a function for this. >>>> >>>> There are a number of reasons as to why I think these functions should >>>> be considered, but I'll provide only two for now: >>>> >>>> 1. There is already a way of updating multiple key-value pairs >>>> simultaneously for maps using %{map | k1 => v1, k2 => v2}. But this >>>> unfortunately does not support passing a literal keyword list after the >>>> cons operator. >>>> - My first instinct was to see if I could expand the special >>>> update syntax to handle keyword lists, but I wasn't able to find >>>> where it >>>> is in the codebase. If someone could point that out for me because >>>> I'd like >>>> to learn how it works, I'd greatly appreciate it. >>>> 2. It would be somewhat analogous to Kernel.struct!/2, where >>>> keyword lists can be passed as the second argument to update several >>>> fields >>>> within a struct. Seeing as how structs are maps, it only makes sense >>>> there >>>> should be a way that maps could be updated in a similar manner from >>>> within >>>> the Map module. >>>> >>>> >>>> I have already implemented the four functions, complete with docs, >>>> examples, and passing tests. But I wanted confirmation from the core team >>>> if a PR is welcome for this addition. Any opinions? >>>> >>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "elixir-lang-core" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to elixir-lang-co...@googlegroups.com. >>>> To view this discussion on the web visit >>>> https://groups.google.com/d/msgid/elixir-lang-core/7c79a2b8-3a3c-48f9-a4d0-7d2e07c851e4n%40googlegroups.com >>>> >>>> <https://groups.google.com/d/msgid/elixir-lang-core/7c79a2b8-3a3c-48f9-a4d0-7d2e07c851e4n%40googlegroups.com?utm_medium=email&utm_source=footer> >>>> . >>>> >>> -- >> You received this message because you are subscribed to the Google Groups >> "elixir-lang-core" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to elixir-lang-co...@googlegroups.com. >> > To view this discussion on the web visit >> https://groups.google.com/d/msgid/elixir-lang-core/63cf4231-5747-4f8e-99f7-87a68a7ab664n%40googlegroups.com >> >> <https://groups.google.com/d/msgid/elixir-lang-core/63cf4231-5747-4f8e-99f7-87a68a7ab664n%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> > -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/cb88ccf3-ece7-47b5-a6d6-7ba5253482bfn%40googlegroups.com.