File 7521-Use-ets-_lookup-in-ets-foldl-and-ets-foldr.patch of Package erlang
From 0f671b6c2990032c98d0b32767f31cdc50824b36 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muska=C5=82a?= <micmus@fb.com>
Date: Thu, 25 Jan 2024 10:26:49 +0000
Subject: [PATCH 1/2] Use ets:*_lookup in ets:foldl and ets:foldr
Using those functions allow cutting the number of ETS accesses in half.
However, they do have slightly higher memory overhead, due to the extra tuple.
This overhead will be relatively smaller, the more complex objects are stored in ETS.
The new implementation was faster in practice even for the simplest 2-tuple objects.
---
lib/stdlib/src/ets.erl | 32 +++++++++++---------------------
1 file changed, 11 insertions(+), 21 deletions(-)
diff --git a/lib/stdlib/src/ets.erl b/lib/stdlib/src/ets.erl
index 883e9ad26b..3716c5bfa2 100644
--- a/lib/stdlib/src/ets.erl
+++ b/lib/stdlib/src/ets.erl
@@ -690,22 +690,17 @@ the traversal.
foldl(F, Accu, T) ->
ets:safe_fixtable(T, true),
- First = ets:first(T),
+ First = ets:first_lookup(T),
try
do_foldl(F, Accu, First, T)
after
ets:safe_fixtable(T, false)
end.
-do_foldl(F, Accu0, Key, T) ->
- case Key of
- '$end_of_table' ->
- Accu0;
- _ ->
- do_foldl(F,
- lists:foldl(F, Accu0, ets:lookup(T, Key)),
- ets:next(T, Key), T)
- end.
+do_foldl(_F, Accu, '$end_of_table', _T) -> Accu;
+do_foldl(F, Accu0, {Key, Objects}, T) ->
+ Accu = lists:foldl(F, Accu0, Objects),
+ do_foldl(F, Accu, ets:next_lookup(T, Key), T).
-spec foldr(Function, Acc0, Table) -> Acc1 when
Function :: fun((Element :: term(), AccIn) -> AccOut),
@@ -717,22 +722,17 @@ the traversal.
foldr(F, Accu, T) ->
ets:safe_fixtable(T, true),
- Last = ets:last(T),
+ Last = ets:last_lookup(T),
try
do_foldr(F, Accu, Last, T)
- after
+ after
ets:safe_fixtable(T, false)
end.
-do_foldr(F, Accu0, Key, T) ->
- case Key of
- '$end_of_table' ->
- Accu0;
- _ ->
- do_foldr(F,
- lists:foldr(F, Accu0, ets:lookup(T, Key)),
- ets:prev(T, Key), T)
- end.
+do_foldr(_F, Accu, '$end_of_table', _T) -> Accu;
+do_foldr(F, Accu0, {Key, Objects}, T) ->
+ Accu = lists:foldr(F, Accu0, Objects),
+ do_foldr(F, Accu, ets:prev_lookup(T, Key), T).
-spec from_dets(Table, DetsTab) -> 'true' when
Table :: table(),
--
2.35.3