Hope this helps, and happy old year/new year :-),
~Marten On 31-12-2021 01:01, Paul Alexander wrote:
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 subscribedto 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 theGoogle 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 <https://groups.google.com/d/msgid/elixir-lang-core/cb88ccf3-ece7-47b5-a6d6-7ba5253482bfn%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/d97da267-161b-7164-c5f7-aa3453beffce%40resilia.nl.
OpenPGP_signature
Description: OpenPGP digital signature