Skip to content

Instantly share code, notes, and snippets.

@bjorng
Created October 17, 2018 08:08
Show Gist options
  • Save bjorng/bc9627e45908249af44917789df25a99 to your computer and use it in GitHub Desktop.
Save bjorng/bc9627e45908249af44917789df25a99 to your computer and use it in GitHub Desktop.
Simple benchmarking of persistent terms
-module(pt_benchmark).
-compile([export_all,nowarn_export_all]).
b() ->
%% run(fun pt_imm/1, fun pdict_imm/1),
%% run(fun pt/1, fun pdict/1),
%% run(fun pt_striped/1, fun pdict_striped/1),
%% run(fun pt_record/1, fun pdict_record/1),
run(fun ets_imm/1, fun pt_imm/1),
run(fun ets/1, fun pt/1),
run(fun ets_striped/1, fun pt_striped/1),
run(fun ets_record/1, fun pt_record/1),
ok.
run(F1, F2) ->
T1 = run(F1),
T2 = run(F2),
io:format("~.8p ~.8p ~p\n", [T1,T2,round(T1/T2*100)/100]),
ok.
run(F) ->
Iter = 10000000,
Run = fun() ->
Res = timer:tc(fun() -> F(Iter) end),
exit({result,Res})
end,
{Pid,Ref} = spawn_monitor(Run),
receive
{'DOWN',Ref,process,Pid,Result} ->
{result,{Tc,ok}} = Result,
Tc
end.
%% -define(PT_KEY, {?MODULE,ref}).
-define(PT_KEY, b_ref).
pt(Iter) ->
persistent_term:put(?PT_KEY, make_ref),
pt_1(Iter).
pt_1(0) ->
ok;
pt_1(Iter) ->
_Ref = id(persistent_term:get(?PT_KEY)),
pt_1(Iter-1).
pdict(Iter) ->
erlang:put(?PT_KEY, make_ref),
pdict_1(Iter).
pdict_1(0) ->
ok;
pdict_1(Iter) ->
_ = id(erlang:get(?PT_KEY)),
pdict_1(Iter-1).
ets(Iter) ->
my_table = ets:new(my_table, [named_table]),
ets:insert(my_table, {key,make_ref()}),
ets_1(Iter).
ets_1(0) ->
ok;
ets_1(Iter) ->
_Ref = ets:lookup_element(my_table, key, 2),
ets_1(Iter-1).
pt_striped(Iter) ->
persistent_term:put(?PT_KEY, striped()),
pt_striped_1(Iter).
pt_striped_1(0) ->
ok;
pt_striped_1(Iter) ->
Refs = persistent_term:get(?PT_KEY),
_ = element(erlang:system_info(scheduler_id), Refs),
pt_striped_1(Iter-1).
pdict_striped(Iter) ->
erlang:put(?PT_KEY, striped()),
pdict_striped_1(Iter).
pdict_striped_1(0) ->
ok;
pdict_striped_1(Iter) ->
Refs = erlang:get(?PT_KEY),
_ = element(erlang:system_info(scheduler_id), Refs),
pdict_striped_1(Iter-1).
ets_striped(Iter) ->
my_table = ets:new(my_table, [named_table]),
Entries = [{I,make_ref()} || I <- lists:seq(1, erlang:system_info(schedulers))],
ets:insert(my_table, Entries),
ets_striped_1(Iter).
ets_striped_1(0) ->
ok;
ets_striped_1(Iter) ->
_Ref = ets:lookup_element(my_table, erlang:system_info(scheduler_id), 2),
ets_striped_1(Iter-1).
%% ets_striped(Iter) ->
%% my_table = ets:new(my_table, [named_table]),
%% ets:insert(my_table, {key,striped()}),
%% ets_striped_1(Iter).
%% ets_striped_1(0) ->
%% ok;
%% ets_striped_1(Iter) ->
%% Refs = ets:lookup_element(my_table, key, 2),
%% Ref = element(erlang:system_info(scheduler_id), Refs),
%% id(Ref),
%% ets_striped_1(Iter-1).
pt_record(Iter) ->
persistent_term:put(?PT_KEY, record()),
pt_record_1(Iter).
pt_record_1(0) ->
ok;
pt_record_1(Iter) ->
Rec = persistent_term:get(?PT_KEY),
id(Rec),
pt_record_1(Iter-1).
pdict_record(Iter) ->
erlang:put(?PT_KEY, record()),
pt_record_1(Iter).
pdict_record_1(0) ->
ok;
pdict_record_1(Iter) ->
Rec = erlang:get(?PT_KEY),
id(Rec),
pdict_record_1(Iter-1).
ets_record(Iter) ->
my_table = ets:new(my_table, [named_table]),
ets:insert(my_table, record()),
ets_record_1(Iter).
ets_record_1(0) ->
ok;
ets_record_1(Iter) ->
[Rec] = ets:lookup(my_table, tag),
id(Rec),
ets_record_1(Iter-1).
pt_imm(Iter) ->
persistent_term:put(?PT_KEY, record()),
pt_imm_1(Iter).
pt_imm_1(0) ->
ok;
pt_imm_1(Iter) ->
_ = id(persistent_term:get(?PT_KEY)),
pt_imm_1(Iter-1).
pdict_imm(Iter) ->
erlang:put(?PT_KEY, record()),
pdict_imm_1(Iter).
pdict_imm_1(0) ->
ok;
pdict_imm_1(Iter) ->
_ = id(erlang:get(?PT_KEY)),
pdict_imm_1(Iter-1).
ets_imm(Iter) ->
my_table = ets:new(my_table, [named_table]),
ets:insert(my_table, {key,imm()}),
ets_imm_1(Iter).
ets_imm_1(0) ->
ok;
ets_imm_1(Iter) ->
_ = id(ets:lookup_element(my_table, key, 2)),
ets_imm_1(Iter-1).
striped() ->
list_to_tuple([make_ref() || _ <- lists:seq(1, erlang:system_info(schedulers))]).
record() ->
list_to_tuple([tag|lists:seq(2, 64)]).
imm() ->
value.
id(I) ->
I.
@taiyow
Copy link

taiyow commented Dec 17, 2018

Hi!
Thanks to this benchmark.

make_ref in pt/1 and pdict/1 should be a function?

--- pt_benchmark.erl.orig       2018-12-17 02:38:10.033387893 +0000
+++ pt_benchmark.erl    2018-12-17 02:38:42.368373665 +0000
@@ -35,7 +35,7 @@
 -define(PT_KEY, b_ref).

 pt(Iter) ->
-    persistent_term:put(?PT_KEY, make_ref),
+    persistent_term:put(?PT_KEY, make_ref()),
     pt_1(Iter).

 pt_1(0) ->
@@ -45,7 +45,7 @@
     pt_1(Iter-1).

 pdict(Iter) ->
-    erlang:put(?PT_KEY, make_ref),
+    erlang:put(?PT_KEY, make_ref()),
     pdict_1(Iter).

 pdict_1(0) ->

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment