[erlang-questions] ets:slot() on ordered_set
Ulf Wiger (TN/EAB)
ulf.wiger@REDACTED
Tue Sep 4 16:45:13 CEST 2007
I had reason to look into the behaviour of ets:slot/2
on ordered_set tables.
It's either really cool, or really bad, depending on
what you want to do with it.
The thing is that erl_db_tree.c caches the slot position
from the previous operation, and the function db_slot()
traverses the tree from the cached position to the new
position. This is wonderful if the slot asked for is
adjacent to the previous slot; otherwise - not so
wonderful.
Consider the sloppy benchmark below. It creates a
table, and fills it with data. It then reads each
slot, once in order, and once with the positions
shuffled about.
Eshell V5.5.5 (abort with ^G)
1> c(slots).
{ok,slots}
2> slots:ordset(10).
{1.70000,0.600000,2}
3> slots:ordset(100).
{2.76000,0.550000,5}
4> slots:ordset(1000).
{24.2180,0.533000,45}
5> slots:ordset(10000).
{290.518,0.617900,470}
The values are {TimeShuffled, TimeOrdered, Ratio},
and it's very obvious that jumping about using slot()
in a large ordered_set table is a very bad idea.
BR,
Ulf W
-module(slots).
-compile(export_all).
s([A|B],T) ->
ets:slot(T, A),
s(B,T);
s([],_) ->
ok.
ordset(N) -> go(ordered_set,N).
go(Type,N) ->
T = ets:new(t,[Type]),
L = lists:seq(1,N),
[ets:insert(T, {N1}) || N1 <- lists:seq(1,N)],
L1 = shuffle(L),
{T1,ok} = timer:tc(?MODULE,s,[L1,T]),
{T2,ok} = timer:tc(?MODULE,s,[L,T]),
{T1/N, T2/N, T1 div T2}.
shuffle(L) ->
Mid = length(L) div 2,
L1 = lists:sublist(L,1,Mid),
L2 = lists:nthtail(Mid,L),
splice(L1,lists:reverse(L2)).
splice([H|T],[H1|T1]) ->
[H,H1 | splice(T,T1)];
splice([],[H]) -> [H];
splice([H],[]) -> [H];
splice([], []) ->
[].
More information about the erlang-questions
mailing list