Last active
October 23, 2021 11:20
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-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