Skip to content

Instantly share code, notes, and snippets.

@ostinelli
Last active October 23, 2021 11:20
Show Gist options
  • Save ostinelli/e13ef2f5c995d683c2253475eedfe9f1 to your computer and use it in GitHub Desktop.
Save ostinelli/e13ef2f5c995d683c2253475eedfe9f1 to your computer and use it in GitHub Desktop.
Erlang take values from KV stores (dict vs orddict vs maps vs gb_sets vs ets set vs ets bag benchmark)
-module(kv_bench).
-compile([export_all]).
main(Count) ->
Values = lists:foldl(fun(C, Acc) ->
[{C, {v, C}} | Acc]
end, [], lists:seq(1, Count)),
{TimeDict, ResultDict} = timer:tc(?MODULE, get_last_dict, [Count, Values]),
io:format("DICT (~p): ~p sec~n", [ResultDict, TimeDict / 1000000]),
{TimeOrdDict, ResultOrdDict} = timer:tc(?MODULE, get_last_orddict, [Count, Values]),
io:format("ORDDICT (~p): ~p sec~n", [ResultOrdDict, TimeOrdDict / 1000000]),
{TimeMap, ResultMap} = timer:tc(?MODULE, get_last_maps, [Count, Values]),
io:format("MAP (~p): ~p sec~n", [ResultMap, TimeMap / 1000000]),
{TimeGbTrees, ResultGbTrees} = timer:tc(?MODULE, get_last_gb_trees, [Count, Values]),
io:format("GB TREES (~p): ~p sec~n", [ResultGbTrees, TimeGbTrees / 1000000]),
{TimeEtsSet, ResultEtsSet} = timer:tc(?MODULE, get_last_ets_set, [Count, Values]),
io:format("ETS SET (~p): ~p sec~n", [ResultEtsSet, TimeEtsSet / 1000000]),
{TimeEtsBag, ResultEtsBag} = timer:tc(?MODULE, get_last_ets_bag, [Count, Values]),
io:format("ETS BAG (~p): ~p sec~n", [ResultEtsBag, TimeEtsBag / 1000000]).
get_last_dict(Count, Values) ->
Dict = dict:from_list(Values),
{Value, _} = lists:foldl(fun(C, {_, D}) ->
dict:take(C, D)
end, {undefined, Dict}, lists:seq(1, Count)),
Value.
get_last_orddict(Count, Values) ->
OrdDict = orddict:from_list(Values),
{Value, _} = lists:foldl(fun(C, {_, OD}) ->
orddict:take(C, OD)
end, {undefined, OrdDict}, lists:seq(1, Count)),
Value.
get_last_maps(Count, Values) ->
Map = maps:from_list(Values),
{Value, _} = lists:foldl(fun(C, {_, M}) ->
maps:take(C, M)
end, {undefined, Map}, lists:seq(1, Count)),
Value.
get_last_gb_trees(Count, Values) ->
GbTrees = gb_trees:from_orddict(orddict:from_list(Values)),
{Value, _} = lists:foldl(fun(C, {_, GBT}) ->
gb_trees:take(C, GBT)
end, {undefined, GbTrees}, lists:seq(1, Count)),
Value.
get_last_ets_set(Count, Values) ->
%% create
Tid = ets:new(syn_tmp_multi_call, [set, {read_concurrency, true}, {decentralized_counters, true}]),
lists:foreach(fun({K, V}) -> ets:insert(Tid, {K, V}) end, Values),
%% take
Value = lists:foldl(fun(C, _) ->
[{_, V}] = ets:take(Tid, C),
V
end, undefined, lists:seq(1, Count)),
ets:delete(Tid),
Value.
get_last_ets_bag(Count, Values) ->
%% create
Tid = ets:new(syn_tmp_multi_call, [bag, {read_concurrency, true}, {decentralized_counters, true}]),
lists:foreach(fun({K, V}) -> ets:insert(Tid, {K, V}) end, Values),
%% take
Value = lists:foldl(fun(C, _) ->
[{_, V}] = ets:take(Tid, C),
V
end, undefined, lists:seq(1, Count)),
ets:delete(Tid),
Value.
%% RESULTS for 1_000_000
%%
%% 1> kv_bench:main(100000).
%% DICT ({v,1000000}): 129.512306 sec
%% ORDDICT ({v,1000000}): 0.081126 sec
%% MAP ({v,1000000}): 1.405384 sec
%% GB TREES ({v,1000000}): 0.469989 sec
%% ETS SET ({v,1000000}): 1.035116 sec
%% ETS BAG v({v,1000000}): 1.074673 sec
%% RESULTS for 10_000_000 (dict omitted)
%%
%% ORDDICT ({v,10000000}): 2.531998 sec
%% MAP ({v,10000000}): 21.563569 sec
%% GB TREES ({v,10000000}): 6.407117 sec
%% ETS SET ({v,10000000}): 13.96758 sec
%% ETS BAG ({v,10000000}): 13.444932 sec
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment