File 2971-Optimize-maps-merge_with-3-for-maps-of-equal-size.patch of Package erlang
From c6ad0d56eb9ef333ecbb931acc1deca236b5aa07 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Valim?= <jose.valim@dashbit.co>
Date: Sun, 28 Apr 2024 13:05:08 +0200
Subject: [PATCH] Optimize maps:merge_with/3 for maps of equal size
Previously, we were wrapping the combiner function
without an actual need. We also use this opportunity
to remove an unused argument.
---
lib/stdlib/src/maps.erl | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/lib/stdlib/src/maps.erl b/lib/stdlib/src/maps.erl
index c3c7da9284..f48a5673af 100644
--- a/lib/stdlib/src/maps.erl
+++ b/lib/stdlib/src/maps.erl
@@ -379,33 +379,30 @@ _Example:_
merge_with(Combiner, Map1, Map2) when is_map(Map1),
is_map(Map2),
is_function(Combiner, 3) ->
- case map_size(Map1) > map_size(Map2) of
+ %% Use >= because we want to avoid reversing the combiner if we can
+ case map_size(Map1) >= map_size(Map2) of
true ->
Iterator = maps:iterator(Map2),
- merge_with_1(maps:next(Iterator),
- Map1,
- Map2,
- Combiner);
+ merge_with_1(maps:next(Iterator), Map1, Combiner);
false ->
Iterator = maps:iterator(Map1),
merge_with_1(maps:next(Iterator),
Map2,
- Map1,
fun(K, V1, V2) -> Combiner(K, V2, V1) end)
end;
merge_with(Combiner, Map1, Map2) ->
error_with_info(error_type_merge_intersect(Map1, Map2, Combiner),
[Combiner, Map1, Map2]).
-merge_with_1({K, V2, Iterator}, Map1, Map2, Combiner) ->
+merge_with_1({K, V2, Iterator}, Map1, Combiner) ->
case Map1 of
#{ K := V1 } ->
NewMap1 = Map1#{ K := Combiner(K, V1, V2) },
- merge_with_1(maps:next(Iterator), NewMap1, Map2, Combiner);
+ merge_with_1(maps:next(Iterator), NewMap1, Combiner);
#{ } ->
- merge_with_1(maps:next(Iterator), maps:put(K, V2, Map1), Map2, Combiner)
+ merge_with_1(maps:next(Iterator), maps:put(K, V2, Map1), Combiner)
end;
-merge_with_1(none, Result, _, _) ->
+merge_with_1(none, Result, _) ->
Result.
--
2.35.3