From 923230571f84ff5c5d9e020435deada2b7cc2ea9 Mon Sep 17 00:00:00 2001 From: AICells <1713699517@qq.com> Date: Mon, 13 Jan 2020 23:23:22 +0800 Subject: [PATCH] =?UTF-8?q?erlang=E6=95=B0=E6=8D=AE=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E6=95=88=E7=8E=87=E7=9B=B8=E5=85=B3=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/erlang数据结构相关.md | 29 ++++++++++++- .../DsTest/{arrayDs.erl => utArrayDs.erl} | 16 ++++---- .../DsTest/{atomicsDs.erl => utAtomicsDs.erl} | 22 +++++----- .../DsTest/{dictDs.erl => utDictDs.erl} | 30 +++++++------- .../DsTest/{etsOrdDs.erl => utEtsOrdDs.erl} | 26 ++++++------ .../DsTest/{etsSetDs.erl => utEtsSetDs.erl} | 26 ++++++------ .../DsTest/{gb_setsDs.erl => utGb_setsDs.erl} | 16 ++++---- .../{gb_treesDs.erl => utGb_treesDs.erl} | 16 ++++---- .../DsTest/{listsDs.erl => utListsDs.erl} | 25 ++++++----- .../DsTest/{mapsDs.erl => utMapsDs.erl} | 16 ++++---- .../DsTest/{orddictDs.erl => utOrddictDs.erl} | 21 ++++++---- .../DsTest/{ordsets.erl => utOrdsetsDs.erl} | 24 +++++------ .../{persistentTermDs.erl => utPTermDs.erl} | 20 ++++----- src/testCase/DsTest/{pdDs.erl => utPdDs.erl} | 16 ++++---- .../DsTest/{setsDs.erl => utSetsDs.erl} | 16 ++++---- src/testCase/DsTest/utTestDs.erl | 41 +++++++++++++++++-- .../DsTest/{tupleDs.erl => utTupleDs.erl} | 21 ++++++---- src/testCase/utTestDS.erl | 35 ---------------- 18 files changed, 226 insertions(+), 190 deletions(-) rename src/testCase/DsTest/{arrayDs.erl => utArrayDs.erl} (74%) rename src/testCase/DsTest/{atomicsDs.erl => utAtomicsDs.erl} (59%) rename src/testCase/DsTest/{dictDs.erl => utDictDs.erl} (57%) rename src/testCase/DsTest/{etsOrdDs.erl => utEtsOrdDs.erl} (61%) rename src/testCase/DsTest/{etsSetDs.erl => utEtsSetDs.erl} (61%) rename src/testCase/DsTest/{gb_setsDs.erl => utGb_setsDs.erl} (69%) rename src/testCase/DsTest/{gb_treesDs.erl => utGb_treesDs.erl} (73%) rename src/testCase/DsTest/{listsDs.erl => utListsDs.erl} (62%) rename src/testCase/DsTest/{mapsDs.erl => utMapsDs.erl} (74%) rename src/testCase/DsTest/{orddictDs.erl => utOrddictDs.erl} (67%) rename src/testCase/DsTest/{ordsets.erl => utOrdsetsDs.erl} (62%) rename src/testCase/DsTest/{persistentTermDs.erl => utPTermDs.erl} (60%) rename src/testCase/DsTest/{pdDs.erl => utPdDs.erl} (73%) rename src/testCase/DsTest/{setsDs.erl => utSetsDs.erl} (69%) rename src/testCase/DsTest/{tupleDs.erl => utTupleDs.erl} (64%) delete mode 100644 src/testCase/utTestDS.erl diff --git a/src/docs/erlang数据结构相关.md b/src/docs/erlang数据结构相关.md index da03ab3..4b84317 100644 --- a/src/docs/erlang数据结构相关.md +++ b/src/docs/erlang数据结构相关.md @@ -290,4 +290,31 @@ Unique Integers on a Runtime System Instance (请注意:不常用的模块ordset和 orddict只是有序列表,因此对于诸如插入之类的常见操作具有O(n)) % Suggestion: % elments count: 0 - 100 | 100 - 10000 | 10000 - - % our select : list | ets | gb_tree \ No newline at end of file + % our select : list | ets | gb_tree + + + %% 用于测试erlang各种数据结构 读写遍历等操作的效率 + %%  lists ,maps 和record是erlang最为常用的数据结构,lists使用方便简单,maps则查询高效,record则需要预定义, + %% 可扩展性差,各有各的优。本文做一下lists和maps的性能对比(再对比一下dict),代码如下(record操作不便则不做比较)。 + + %%通过注释部分代码做以下测试 + %%timer:tc(lib_test, test_struct, [10000,#{}]). + %%timer:tc(lib_test, test_struct, [10000,[]]). + + %% 做10000次的插入查询测试结果: + %% + %%     lists 50736微秒 + %%     maps 4670微秒 + %%     dict 60236微秒 + %% 做10000次的遍历结果: + %% + %%     lists 523微秒 + %%     maps 8337微秒 + %%     dict 4426微秒 + %% 对比总结: + %% + %%     对比测试数据maps在查询性能上比lists高10倍以上, 而在遍历上lists则更优。对于频繁插入和查询的数据,maps是最佳的选择, + %% lists则适用于广播列表之类需要遍历的数据。除此之外,个人觉得在使用上lists 比maps更为方便,因为lists模块提供了大量实用的函数, + %% 单单在排序上,maps的实用性就不如lists了,所以在数据结构选择上就需要多多斟酌。另外record在查询上使用的是模式匹配,性能只会更高, + %% 但需要提前定义字段,可扩展性差,在热更这块有不少坑,maps也可以用模式匹配查询,但也要确保key值存在,不然就nomatch, + %% 但整体上maps更优于record,故建议用maps替代record。 \ No newline at end of file diff --git a/src/testCase/DsTest/arrayDs.erl b/src/testCase/DsTest/utArrayDs.erl similarity index 74% rename from src/testCase/DsTest/arrayDs.erl rename to src/testCase/DsTest/utArrayDs.erl index ff3def4..1ea9ec9 100644 --- a/src/testCase/DsTest/arrayDs.erl +++ b/src/testCase/DsTest/utArrayDs.erl @@ -1,22 +1,22 @@ --module(arrayDs). +-module(utArrayDs). -compile([nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). -export([start/2]). start(Num, Pid) -> Ds = init(Num), - erlang:statistics(wall_clock), + Time1 = erlang:system_time(nanosecond), NewDsI = insert(Num - 1, Ds), - {_, TimeI} = erlang:statistics(wall_clock), + Time2 = erlang:system_time(nanosecond), NewDsR = read(Num - 1, NewDsI), - {_, TimeR} = erlang:statistics(wall_clock), + Time3 = erlang:system_time(nanosecond), NewDsU = update(Num - 1, NewDsR), - {_, TimeU} = erlang:statistics(wall_clock), + Time4 = erlang:system_time(nanosecond), NewDsF = for(Num - 1, NewDsU), - {_, TimeF} = erlang:statistics(wall_clock), + Time5 = erlang:system_time(nanosecond), delete(Num - 1, NewDsF), - {_, TimeD} = erlang:statistics(wall_clock), - erlang:send(Pid, {over, self(), TimeI, TimeR, TimeU, TimeF, not_support}), + Time6 = erlang:system_time(nanosecond), + erlang:send(Pid, {over, self(), Time2 - Time1, Time3 - Time2, Time4 - Time3, Time5 - Time4, not_support}), exit(normal). init(Num) -> diff --git a/src/testCase/DsTest/atomicsDs.erl b/src/testCase/DsTest/utAtomicsDs.erl similarity index 59% rename from src/testCase/DsTest/atomicsDs.erl rename to src/testCase/DsTest/utAtomicsDs.erl index 98e3f4b..645b951 100644 --- a/src/testCase/DsTest/atomicsDs.erl +++ b/src/testCase/DsTest/utAtomicsDs.erl @@ -1,22 +1,22 @@ --module(atomicsDs). +-module(utAtomicsDs). -compile([nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). -export([start/2]). start(Num, Pid) -> Ds = init(Num), - erlang:statistics(wall_clock), + Time1 = erlang:system_time(nanosecond), NewDsI = insert(Num, Ds), - {_, TimeI} = erlang:statistics(wall_clock), + Time2 = erlang:system_time(nanosecond), NewDsR = read(Num, NewDsI), - {_, TimeR} = erlang:statistics(wall_clock), + Time3 = erlang:system_time(nanosecond), NewDsU = update(Num, NewDsR), - {_, TimeU} = erlang:statistics(wall_clock), + Time4 = erlang:system_time(nanosecond), NewDsF = for(Num, NewDsU), - {_, TimeF} = erlang:statistics(wall_clock), + Time5 = erlang:system_time(nanosecond), delete(Num, NewDsF), - {_, TimeD} = erlang:statistics(wall_clock), - erlang:send(Pid, {over, self(), TimeI, TimeR, TimeU, TimeF, not_support}), + Time6 = erlang:system_time(nanosecond), + erlang:send(Pid, {over, self(), Time2 - Time1, Time3 - Time2, Time4 - Time3, Time5 - Time4, not_support}), exit(normal). init(Num) -> @@ -37,8 +37,8 @@ read(Num, Ds) -> update(0, Ds) -> Ds; update(Num, Ds) -> - NewDs = atomics:add(Ds, Num, 1), - update(Num - 1, NewDs). + atomics:add(Ds, Num, 1), + update(Num - 1, Ds). for(0, Ds) -> Ds; @@ -46,7 +46,7 @@ for(Num, Ds) -> atomics:get(Ds, Num), for(Num - 1, Ds). -delete(0, Ds) -> +delete(Num, Ds) -> ok. diff --git a/src/testCase/DsTest/dictDs.erl b/src/testCase/DsTest/utDictDs.erl similarity index 57% rename from src/testCase/DsTest/dictDs.erl rename to src/testCase/DsTest/utDictDs.erl index e68f0c0..4b2a63f 100644 --- a/src/testCase/DsTest/dictDs.erl +++ b/src/testCase/DsTest/utDictDs.erl @@ -1,22 +1,22 @@ --module(dictDs). +-module(utDictDs). -compile([nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). -export([start/2]). start(Num, Pid) -> Ds = init(Num), - erlang:statistics(wall_clock), + Time1 = erlang:system_time(nanosecond), NewDsI = insert(Num, Ds), - {_, TimeI} = erlang:statistics(wall_clock), + Time2 = erlang:system_time(nanosecond), NewDsR = read(Num, NewDsI), - {_, TimeR} = erlang:statistics(wall_clock), + Time3 = erlang:system_time(nanosecond), NewDsU = update(Num, NewDsR), - {_, TimeU} = erlang:statistics(wall_clock), - NewDictF = for(Num, NewDsU), - {_, TimeF} = erlang:statistics(wall_clock), - delete(Num, NewDictF), - {_, TimeD} = erlang:statistics(wall_clock), - erlang:send(Pid, {over, self(), TimeI, TimeR, TimeU, TimeF, TimeD}), + Time4 = erlang:system_time(nanosecond), + NewDsF = for(Num, NewDsU), + Time5 = erlang:system_time(nanosecond), + delete(Num, NewDsF), + Time6 = erlang:system_time(nanosecond), + erlang:send(Pid, {over, self(), Time2 - Time1, Time3 - Time2, Time4 - Time3, Time5 - Time4, Time6 - Time5}), exit(normal). init(_Num) -> @@ -27,14 +27,14 @@ insert(0, Ds) -> insert(Num, Ds) -> Key = utTestDs:makeK(Num), Value = utTestDs:makeV(Num), - NewDs = Ds:store(Key, Value, Ds), + NewDs = dict:store(Key, Value, Ds), insert(Num - 1, NewDs). read(0, Ds) -> Ds; read(Num, Ds) -> Key = utTestDs:makeK(Num), - Value = Ds:find(Key, Ds), + Value = dict:find(Key, Ds), read(Num - 1, Ds). update(0, Ds) -> @@ -42,7 +42,7 @@ update(0, Ds) -> update(Num, Ds) -> Key = utTestDs:makeK(Num), Value = utTestDs:makeV2(Num), - NewDs = Ds:store(Key, Value, Ds), + NewDs = dict:store(Key, Value, Ds), update(Num - 1, NewDs). for(Num, Ds) -> @@ -50,14 +50,14 @@ for(Num, Ds) -> fun(Key, Value, Acc) -> Value end, - List = Ds:fold(Fun, [], Ds), + List = dict:fold(Fun, [], Ds), Ds. delete(0, Ds) -> ok; delete(Num, Ds) -> Key = utTestDs:makeK(Num), - NewDs = Ds:erase(Key, Ds), + NewDs = dict:erase(Key, Ds), delete(Num - 1, NewDs). diff --git a/src/testCase/DsTest/etsOrdDs.erl b/src/testCase/DsTest/utEtsOrdDs.erl similarity index 61% rename from src/testCase/DsTest/etsOrdDs.erl rename to src/testCase/DsTest/utEtsOrdDs.erl index 5713d35..06b878b 100644 --- a/src/testCase/DsTest/etsOrdDs.erl +++ b/src/testCase/DsTest/utEtsOrdDs.erl @@ -1,22 +1,22 @@ --module(etsOrdDs). +-module(utEtsOrdDs). -compile([nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). -export([start/2]). start(Num, Pid) -> Ds = init(Num), - erlang:statistics(wall_clock), + Time1 = erlang:system_time(nanosecond), NewDsI = insert(Num, Ds), - {_, TimeI} = erlang:statistics(wall_clock), + Time2 = erlang:system_time(nanosecond), NewDsR = read(Num, NewDsI), - {_, TimeR} = erlang:statistics(wall_clock), + Time3 = erlang:system_time(nanosecond), NewDsU = update(Num, NewDsR), - {_, TimeU} = erlang:statistics(wall_clock), + Time4 = erlang:system_time(nanosecond), NewDsF = for(Num, NewDsU), - {_, TimeF} = erlang:statistics(wall_clock), + Time5 = erlang:system_time(nanosecond), delete(Num, NewDsF), - {_, TimeD} = erlang:statistics(wall_clock), - erlang:send(Pid, {over, self(), TimeI, TimeR, TimeU, TimeF, TimeD}), + Time6 = erlang:system_time(nanosecond), + erlang:send(Pid, {over, self(), Time2 - Time1, Time3 - Time2, Time4 - Time3, Time5 - Time4, Time6 - Time5}), exit(normal). init(_Num) -> @@ -27,14 +27,14 @@ insert(0, Ds) -> insert(Num, Ds) -> Key = utTestDs:makeK(Num), Value = utTestDs:makeV(Num), - Ds:insert(Ds, {Key, Value}), + ets:insert(Ds, {Key, Value}), insert(Num - 1, Ds). read(0, Ds) -> Ds; read(Num, Ds) -> Key = utTestDs:makeK(Num), - Value = Ds:lookup(Ds, Key), + Value = ets:lookup(Ds, Key), read(Num - 1, Ds). update(0, Ds) -> @@ -42,7 +42,7 @@ update(0, Ds) -> update(Num, Ds) -> Key = utTestDs:makeK(Num), Value = utTestDs:makeV2(Num), - Ds:update_element(Ds, Key, {2, Value}), + ets:update_element(Ds, Key, {2, Value}), update(Num - 1, Ds). for(Num, Ds) -> @@ -50,14 +50,14 @@ for(Num, Ds) -> fun({Key, Value}, Acc) -> Value end, - List = Ds:foldl(Fun, [], Ds), + List = ets:foldl(Fun, [], Ds), Ds. delete(0, Ds) -> ok; delete(Num, Ds) -> Key = utTestDs:makeK(Num), - Ds:delete(Ds, Key), + ets:delete(Ds, Key), delete(Num - 1, Ds). diff --git a/src/testCase/DsTest/etsSetDs.erl b/src/testCase/DsTest/utEtsSetDs.erl similarity index 61% rename from src/testCase/DsTest/etsSetDs.erl rename to src/testCase/DsTest/utEtsSetDs.erl index 19fe56c..f53517b 100644 --- a/src/testCase/DsTest/etsSetDs.erl +++ b/src/testCase/DsTest/utEtsSetDs.erl @@ -1,22 +1,22 @@ --module(etsSetDs). +-module(utEtsSetDs). -compile([nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). -export([start/2]). start(Num, Pid) -> Ds = init(Num), - erlang:statistics(wall_clock), + Time1 = erlang:system_time(nanosecond), NewDsI = insert(Num, Ds), - {_, TimeI} = erlang:statistics(wall_clock), + Time2 = erlang:system_time(nanosecond), NewDsR = read(Num, NewDsI), - {_, TimeR} = erlang:statistics(wall_clock), + Time3 = erlang:system_time(nanosecond), NewDsU = update(Num, NewDsR), - {_, TimeU} = erlang:statistics(wall_clock), + Time4 = erlang:system_time(nanosecond), NewDsF = for(Num, NewDsU), - {_, TimeF} = erlang:statistics(wall_clock), + Time5 = erlang:system_time(nanosecond), delete(Num, NewDsF), - {_, TimeD} = erlang:statistics(wall_clock), - erlang:send(Pid, {over, self(), TimeI, TimeR, TimeU, TimeF, TimeD}), + Time6 = erlang:system_time(nanosecond), + erlang:send(Pid, {over, self(), Time2 - Time1, Time3 - Time2, Time4 - Time3, Time5 - Time4, Time6 - Time5}), exit(normal). init(_Num) -> @@ -27,14 +27,14 @@ insert(0, Ds) -> insert(Num, Ds) -> Key = utTestDs:makeK(Num), Value = utTestDs:makeV(Num), - Ds:insert(Ds, {Key, Value}), + ets:insert(Ds, {Key, Value}), insert(Num - 1, Ds). read(0, Ds) -> Ds; read(Num, Ds) -> Key = utTestDs:makeK(Num), - Value = Ds:lookup(Ds, Key), + Value = ets:lookup(Ds, Key), read(Num - 1, Ds). update(0, Ds) -> @@ -42,7 +42,7 @@ update(0, Ds) -> update(Num, Ds) -> Key = utTestDs:makeK(Num), Value = utTestDs:makeV2(Num), - Ds:update_element(Ds, Key, {2, Value}), + ets:update_element(Ds, Key, {2, Value}), update(Num - 1, Ds). for(Num, Ds) -> @@ -50,14 +50,14 @@ for(Num, Ds) -> fun({Key, Value}, Acc) -> Value end, - List = Ds:foldl(Fun, [], Ds), + List = ets:foldl(Fun, [], Ds), Ds. delete(0, Ds) -> ok; delete(Num, Ds) -> Key = utTestDs:makeK(Num), - Ds:delete(Ds, Key), + ets:delete(Ds, Key), delete(Num - 1, Ds). diff --git a/src/testCase/DsTest/gb_setsDs.erl b/src/testCase/DsTest/utGb_setsDs.erl similarity index 69% rename from src/testCase/DsTest/gb_setsDs.erl rename to src/testCase/DsTest/utGb_setsDs.erl index 2a8260c..aaf600d 100644 --- a/src/testCase/DsTest/gb_setsDs.erl +++ b/src/testCase/DsTest/utGb_setsDs.erl @@ -1,22 +1,22 @@ --module(gb_setsDs). +-module(utGb_setsDs). -compile([nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). -export([start/2]). start(Num, Pid) -> Ds = init(Num), - erlang:statistics(wall_clock), + Time1 = erlang:system_time(nanosecond), NewDsI = insert(Num, Ds), - {_, TimeI} = erlang:statistics(wall_clock), + Time2 = erlang:system_time(nanosecond), NewDsR = read(Num, NewDsI), - {_, TimeR} = erlang:statistics(wall_clock), + Time3 = erlang:system_time(nanosecond), NewDsU = update(Num, NewDsR), - {_, TimeU} = erlang:statistics(wall_clock), + Time4 = erlang:system_time(nanosecond), NewDsF = for(Num, NewDsU), - {_, TimeF} = erlang:statistics(wall_clock), + Time5 = erlang:system_time(nanosecond), delete(Num, NewDsF), - {_, TimeD} = erlang:statistics(wall_clock), - erlang:send(Pid, {over, self(), TimeI, TimeR, not_support, TimeF, TimeD}), + Time6 = erlang:system_time(nanosecond), + erlang:send(Pid, {over, self(), Time2 - Time1, Time3 - Time2, not_support, Time5 - Time4, Time6 - Time5}), exit(normal). init(_Num) -> diff --git a/src/testCase/DsTest/gb_treesDs.erl b/src/testCase/DsTest/utGb_treesDs.erl similarity index 73% rename from src/testCase/DsTest/gb_treesDs.erl rename to src/testCase/DsTest/utGb_treesDs.erl index 8564a9d..1e8275d 100644 --- a/src/testCase/DsTest/gb_treesDs.erl +++ b/src/testCase/DsTest/utGb_treesDs.erl @@ -1,22 +1,22 @@ --module(gb_treesDs). +-module(utGb_treesDs). -compile([nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). -export([start/2]). start(Num, Pid) -> Ds = init(Num), - erlang:statistics(wall_clock), + Time1 = erlang:system_time(nanosecond), NewDsI = insert(Num, Ds), - {_, TimeI} = erlang:statistics(wall_clock), + Time2 = erlang:system_time(nanosecond), NewDsR = read(Num, NewDsI), - {_, TimeR} = erlang:statistics(wall_clock), + Time3 = erlang:system_time(nanosecond), NewDsU = update(Num, NewDsR), - {_, TimeU} = erlang:statistics(wall_clock), + Time4 = erlang:system_time(nanosecond), NewDsF = for(Num, NewDsU), - {_, TimeF} = erlang:statistics(wall_clock), + Time5 = erlang:system_time(nanosecond), delete(Num, NewDsF), - {_, TimeD} = erlang:statistics(wall_clock), - erlang:send(Pid, {over, self(), TimeI, TimeR, TimeU, TimeF, TimeD}), + Time6 = erlang:system_time(nanosecond), + erlang:send(Pid, {over, self(), Time2 - Time1, Time3 - Time2, Time4 - Time3, Time5 - Time4, Time6 - Time5}), exit(normal). init(_Num) -> diff --git a/src/testCase/DsTest/listsDs.erl b/src/testCase/DsTest/utListsDs.erl similarity index 62% rename from src/testCase/DsTest/listsDs.erl rename to src/testCase/DsTest/utListsDs.erl index 3f7ced8..cb323dc 100644 --- a/src/testCase/DsTest/listsDs.erl +++ b/src/testCase/DsTest/utListsDs.erl @@ -1,22 +1,25 @@ --module(listsDs). +-module(utListsDs). -compile([nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). -export([start/2]). -start(Num, Pid) -> +start(Num, Pid) when Num =< 32768 -> Ds = init(Num), - erlang:statistics(wall_clock), + Time1 = erlang:system_time(nanosecond), NewDsI = insert(Num, Ds), - {_, TimeI} = erlang:statistics(wall_clock), - NewArrR = read(Num, NewDsI), - {_, TimeR} = erlang:statistics(wall_clock), - NewDsU = update(Num, NewArrR), - {_, TimeU} = erlang:statistics(wall_clock), + Time2 = erlang:system_time(nanosecond), + NewDsR = read(Num, NewDsI), + Time3 = erlang:system_time(nanosecond), + NewDsU = update(Num, NewDsR), + Time4 = erlang:system_time(nanosecond), NewDsF = for(NewDsU, NewDsU), - {_, TimeF} = erlang:statistics(wall_clock), + Time5 = erlang:system_time(nanosecond), delete(Num, NewDsF), - {_, TimeD} = erlang:statistics(wall_clock), - erlang:send(Pid, {over, self(), TimeI, TimeR, TimeU, TimeF, TimeD}), + Time6 = erlang:system_time(nanosecond), + erlang:send(Pid, {over, self(), Time2 - Time1, Time3 - Time2, Time4 - Time3, Time5 - Time4, Time6 - Time5}), + exit(normal); +start(Num, Pid) -> + erlang:send(Pid, {over, self(), skip, skip, skip, skip, skip}), exit(normal). init(_Num) -> diff --git a/src/testCase/DsTest/mapsDs.erl b/src/testCase/DsTest/utMapsDs.erl similarity index 74% rename from src/testCase/DsTest/mapsDs.erl rename to src/testCase/DsTest/utMapsDs.erl index d0c9f48..624b0a0 100644 --- a/src/testCase/DsTest/mapsDs.erl +++ b/src/testCase/DsTest/utMapsDs.erl @@ -1,22 +1,22 @@ --module(mapsDs). +-module(utMapsDs). -compile([nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). -export([start/2]). start(Num, Pid) -> Ds = init(Num), - erlang:statistics(wall_clock), + Time1 = erlang:system_time(nanosecond), NewDsI = insert(Num, Ds), - {_, TimeI} = erlang:statistics(wall_clock), + Time2 = erlang:system_time(nanosecond), NewDsR = read(Num, NewDsI), - {_, TimeR} = erlang:statistics(wall_clock), + Time3 = erlang:system_time(nanosecond), NewDsU = update(Num, NewDsR), - {_, TimeU} = erlang:statistics(wall_clock), + Time4 = erlang:system_time(nanosecond), NewDsF = for(Num, NewDsU), - {_, TimeF} = erlang:statistics(wall_clock), + Time5 = erlang:system_time(nanosecond), delete(Num, NewDsF), - {_, TimeD} = erlang:statistics(wall_clock), - erlang:send(Pid, {over, self(), TimeI, TimeR, TimeU, TimeF, TimeD}), + Time6 = erlang:system_time(nanosecond), + erlang:send(Pid, {over, self(), Time2 - Time1, Time3 - Time2, Time4 - Time3, Time5 - Time4, Time6 - Time5}), exit(normal). init(_Num) -> diff --git a/src/testCase/DsTest/orddictDs.erl b/src/testCase/DsTest/utOrddictDs.erl similarity index 67% rename from src/testCase/DsTest/orddictDs.erl rename to src/testCase/DsTest/utOrddictDs.erl index e2d8214..99ac9ba 100644 --- a/src/testCase/DsTest/orddictDs.erl +++ b/src/testCase/DsTest/utOrddictDs.erl @@ -1,22 +1,25 @@ --module(orddictDs). +-module(utOrddictDs). -compile([nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). -export([start/2]). -start(Num, Pid) -> +start(Num, Pid) when Num =< 32768 -> Ds = init(Num), - erlang:statistics(wall_clock), + Time1 = erlang:system_time(nanosecond), NewDsI = insert(Num, Ds), - {_, TimeI} = erlang:statistics(wall_clock), + Time2 = erlang:system_time(nanosecond), NewDsR = read(Num, NewDsI), - {_, TimeR} = erlang:statistics(wall_clock), + Time3 = erlang:system_time(nanosecond), NewDsU = update(Num, NewDsR), - {_, TimeU} = erlang:statistics(wall_clock), + Time4 = erlang:system_time(nanosecond), NewDsF = for(Num, NewDsU), - {_, TimeF} = erlang:statistics(wall_clock), + Time5 = erlang:system_time(nanosecond), delete(Num, NewDsF), - {_, TimeD} = erlang:statistics(wall_clock), - erlang:send(Pid, {over, self(), TimeI, TimeR, TimeU, TimeF, TimeD}), + Time6 = erlang:system_time(nanosecond), + erlang:send(Pid, {over, self(), Time2 - Time1, Time3 - Time2, Time4 - Time3, Time5 - Time4, Time6 - Time5}), + exit(normal); +start(Num, Pid) -> + erlang:send(Pid, {over, self(), skip, skip, skip, skip, skip}), exit(normal). init(_Num) -> diff --git a/src/testCase/DsTest/ordsets.erl b/src/testCase/DsTest/utOrdsetsDs.erl similarity index 62% rename from src/testCase/DsTest/ordsets.erl rename to src/testCase/DsTest/utOrdsetsDs.erl index 3398695..566c532 100644 --- a/src/testCase/DsTest/ordsets.erl +++ b/src/testCase/DsTest/utOrdsetsDs.erl @@ -1,22 +1,22 @@ --module(ordsets). +-module(utOrdsetsDs). -compile([nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). -export([start/2]). start(Num, Pid) -> Ds = init(Num), - erlang:statistics(wall_clock), + Time1 = erlang:system_time(nanosecond), NewDsI = insert(Num, Ds), - {_, TimeI} = erlang:statistics(wall_clock), + Time2 = erlang:system_time(nanosecond), NewDsR = read(Num, NewDsI), - {_, TimeR} = erlang:statistics(wall_clock), - NewOrdSetU = update(Num, NewDsR), - {_, TimeU} = erlang:statistics(wall_clock), - NewOrdSetF = for(Num, NewOrdSetU), - {_, TimeF} = erlang:statistics(wall_clock), - delete(Num, NewOrdSetF), - {_, TimeD} = erlang:statistics(wall_clock), - erlang:send(Pid, {over, self(), TimeI, TimeR, not_support, TimeF, TimeD}), + Time3 = erlang:system_time(nanosecond), + NewDsU = update(Num, NewDsR), + Time4 = erlang:system_time(nanosecond), + NewDsF = for(Num, NewDsU), + Time5 = erlang:system_time(nanosecond), + delete(Num, NewDsF), + Time6 = erlang:system_time(nanosecond), + erlang:send(Pid, {over, self(), Time2 - Time1, Time3 - Time2, not_support, Time5 - Time4, Time6 - Time5}), exit(normal). init(_Num) -> @@ -37,7 +37,7 @@ read(Num, Ds) -> Value = ordsets:is_element(Key, Ds), read(Num - 1, Ds). -update(0, Ds) -> +update(Num, Ds) -> Ds. for(Num, Ds) -> diff --git a/src/testCase/DsTest/persistentTermDs.erl b/src/testCase/DsTest/utPTermDs.erl similarity index 60% rename from src/testCase/DsTest/persistentTermDs.erl rename to src/testCase/DsTest/utPTermDs.erl index dab14d0..974ff7c 100644 --- a/src/testCase/DsTest/persistentTermDs.erl +++ b/src/testCase/DsTest/utPTermDs.erl @@ -1,22 +1,22 @@ --module(persistentTermDs). +-module(utPTermDs). -compile([nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). -export([start/2]). start(Num, Pid) -> Ds = init(Num), - erlang:statistics(wall_clock), + Time1 = erlang:system_time(nanosecond), NewDsI = insert(Num, Ds), - {_, TimeI} = erlang:statistics(wall_clock), + Time2 = erlang:system_time(nanosecond), NewDsR = read(Num, NewDsI), - {_, TimeR} = erlang:statistics(wall_clock), + Time3 = erlang:system_time(nanosecond), NewDsU = update(Num, NewDsR), - {_, TimeU} = erlang:statistics(wall_clock), + Time4 = erlang:system_time(nanosecond), NewDsF = for(Num, NewDsU), - {_, TimeF} = erlang:statistics(wall_clock), + Time5 = erlang:system_time(nanosecond), delete(Num, NewDsF), - {_, TimeD} = erlang:statistics(wall_clock), - erlang:send(Pid, {over, self(), TimeI, TimeR, not_support, not_support, not_support}), + Time6 = erlang:system_time(nanosecond), + erlang:send(Pid, {over, self(), Time2 - Time1, Time3 - Time2, not_support, not_support, not_support}), exit(normal). init(Num) -> @@ -37,13 +37,13 @@ read(Num, Ds) -> persistent_term:get(Key), read(Num - 1, Ds). -update(0, Ds) -> +update(Num, Ds) -> Ds. for(Num, Ds) -> Ds. -delete(0, Ds) -> +delete(Num, Ds) -> ok. diff --git a/src/testCase/DsTest/pdDs.erl b/src/testCase/DsTest/utPdDs.erl similarity index 73% rename from src/testCase/DsTest/pdDs.erl rename to src/testCase/DsTest/utPdDs.erl index f403488..13268ea 100644 --- a/src/testCase/DsTest/pdDs.erl +++ b/src/testCase/DsTest/utPdDs.erl @@ -1,22 +1,22 @@ --module(pdDs). +-module(utPdDs). -compile([nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). -export([start/2]). start(Num, Pid) -> Ds = init(Num), - erlang:statistics(wall_clock), + Time1 = erlang:system_time(nanosecond), NewDsI = insert(Num, Ds), - {_, TimeI} = erlang:statistics(wall_clock), + Time2 = erlang:system_time(nanosecond), NewDsR = read(Num, NewDsI), - {_, TimeR} = erlang:statistics(wall_clock), + Time3 = erlang:system_time(nanosecond), NewDsU = update(Num, NewDsR), - {_, TimeU} = erlang:statistics(wall_clock), + Time4 = erlang:system_time(nanosecond), NewDsF = for(Num, NewDsU), - {_, TimeF} = erlang:statistics(wall_clock), + Time5 = erlang:system_time(nanosecond), delete(Num, NewDsF), - {_, TimeD} = erlang:statistics(wall_clock), - erlang:send(Pid, {over, self(), TimeI, TimeR, TimeU, TimeF, not_support}), + Time6 = erlang:system_time(nanosecond), + erlang:send(Pid, {over, self(), Time2 - Time1, Time3 - Time2, Time4 - Time3, Time5 - Time4, Time6 - Time5}), exit(normal). init(Num) -> diff --git a/src/testCase/DsTest/setsDs.erl b/src/testCase/DsTest/utSetsDs.erl similarity index 69% rename from src/testCase/DsTest/setsDs.erl rename to src/testCase/DsTest/utSetsDs.erl index bcdd4d3..0c82d11 100644 --- a/src/testCase/DsTest/setsDs.erl +++ b/src/testCase/DsTest/utSetsDs.erl @@ -1,22 +1,22 @@ --module(setsDs). +-module(utSetsDs). -compile([nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). -export([start/2]). start(Num, Pid) -> Ds = init(Num), - erlang:statistics(wall_clock), + Time1 = erlang:system_time(nanosecond), NewDsI = insert(Num, Ds), - {_, TimeI} = erlang:statistics(wall_clock), + Time2 = erlang:system_time(nanosecond), NewDsR = read(Num, NewDsI), - {_, TimeR} = erlang:statistics(wall_clock), + Time3 = erlang:system_time(nanosecond), NewDsU = update(Num, NewDsR), - {_, TimeU} = erlang:statistics(wall_clock), + Time4 = erlang:system_time(nanosecond), NewDsF = for(Num, NewDsU), - {_, TimeF} = erlang:statistics(wall_clock), + Time5 = erlang:system_time(nanosecond), delete(Num, NewDsF), - {_, TimeD} = erlang:statistics(wall_clock), - erlang:send(Pid, {over, self(), TimeI, TimeR, not_support, TimeF, TimeD}), + Time6 = erlang:system_time(nanosecond), + erlang:send(Pid, {over, self(), Time2 - Time1, Time3 - Time2, not_support, Time5 - Time4, Time6 - Time5}), exit(normal). init(_Num) -> diff --git a/src/testCase/DsTest/utTestDs.erl b/src/testCase/DsTest/utTestDs.erl index ce1cd86..5e0a846 100644 --- a/src/testCase/DsTest/utTestDs.erl +++ b/src/testCase/DsTest/utTestDs.erl @@ -2,7 +2,8 @@ -compile([export_all, nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). -define(V_NUM, [8, 16, 32, 64, 128, 256, 516, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 524288, 1048576]). --define(DsList, [arrayDs, tupleDs, listsDs, setsDs, gb_setsDs, gb_treesDs, dictDs, etsSetDs, etsOrdDs, mapsDs, orddictDs, ordsetsDs, pdDs, atomicsDs, persistentTermDs]). +%-define(V_NUM, [8, 16, 32, 64, 128, 256, 516, 1024]). +-define(DsList, [utArrayDs, utTupleDs, utListsDs, utMapsDs, utPdDs, utEtsSetDs, utEtsOrdDs, utDictDs, utSetsDs, utGb_setsDs, utOrddictDs, utOrdsetsDs, utAtomicsDs, utPTermDs]). recRet(Type, Time) -> erlang:put(Type, Time). @@ -48,10 +49,11 @@ makeV2(N) -> start() -> %% erlang:process_flag(trap_exit, true), - io:format("Ds benchmark...~n~n" ++ "DsName V_Num insert read update for delete ~n" ++ [$= || _ <- lists:seq(1, 51)] ++ "~n", []), + io:format("Ds benchmark..."), runDs(?DsList, ?V_NUM). runDs([Ds | T], VNumList) -> + printTitle(), runNum(VNumList, Ds), runDs(T, VNumList); runDs([], _VNumList) -> @@ -67,7 +69,40 @@ runExe(Num, Ds) -> Pid = erlang:spawn_link(Ds, start, [Num, self()]), receive {over, Pid, Insert, Read, Update, For, Delete} -> - io:format("~-10s ~8B ~8B ~8B ~8B ~8B ~8B~n", [Ds, Num, Insert, Read, Update, For, Delete]); + {_, DsName} = lists:split(2, atom_to_list(Ds)), + io:format("~-9.s ~8.s ~12.s ~12.s ~10.s ~12.s ~10.s ~14.s ~10.s ~12.s ~12.s ~12.s ~n", + [DsName, integer_to_list(Num), timeToStr(Insert), calcPer(Insert, Num), timeToStr(Read), calcPer(Read, Num), timeToStr(Update), calcPer(Update, Num), timeToStr(For), calcPer(For, Num), timeToStr(Delete), calcPer(Delete, Num)]); _ShutDown -> io:format("Ds test shutDown ~p ~p~n",[Ds, Num]) end. + +-define(S, 1000000000). +-define(MS, 1000000). +-define(US, 1000). +-define(NS, 1). + +timeToStr(not_support) -> + <<"noSupport">>; +timeToStr(skip) -> + <<"skip">>; +timeToStr(Time) when Time > ?S -> + float_to_list(Time/?S, [{decimals, 2}, compact]) ++ "s"; +timeToStr(Time) when Time > ?MS -> + float_to_list(Time/?MS, [{decimals, 2}, compact]) ++ "ms"; +timeToStr(Time) when Time > ?US -> + float_to_list(Time/?US, [{decimals, 2}, compact]) ++ "us"; +timeToStr(Time) -> + integer_to_list(Time) ++ "ns". + +calcPer(not_support, _Num) -> + <<"notSupport">>; +calcPer(skip, _Num) -> + <<"skip">>; +calcPer(Time, Num) -> + float_to_list(Time / Num, [{decimals, 2}, compact]) ++ "ns". + +printTitle() -> + io:format("~n~-9.s ~8.s ~12.s ~12.s ~10.s ~12.s ~10.s ~14.s ~10.s ~12.s ~12.s ~12.s ~n", + ["DsName", "V_Num", "insert", "insert/per", "read", "read/per", "update", "update/per", "for", "for/per", "delete", "delete/per"]), + io:format("~s ~n",[[$= || _ <- lists:seq(1, 145)]]). + diff --git a/src/testCase/DsTest/tupleDs.erl b/src/testCase/DsTest/utTupleDs.erl similarity index 64% rename from src/testCase/DsTest/tupleDs.erl rename to src/testCase/DsTest/utTupleDs.erl index dbf0007..4663e71 100644 --- a/src/testCase/DsTest/tupleDs.erl +++ b/src/testCase/DsTest/utTupleDs.erl @@ -1,22 +1,25 @@ --module(tupleDs). +-module(utTupleDs). -compile([nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). -export([start/2]). -start(Num, Pid) -> +start(Num, Pid) when Num =< 65536 -> Ds = init(Num), - erlang:statistics(wall_clock), + Time1 = erlang:system_time(nanosecond), NewDsI = insert(Num, Ds), - {_, TimeI} = erlang:statistics(wall_clock), + Time2 = erlang:system_time(nanosecond), NewDsR = read(Num, NewDsI), - {_, TimeR} = erlang:statistics(wall_clock), + Time3 = erlang:system_time(nanosecond), NewDsU = update(Num, NewDsR), - {_, TimeU} = erlang:statistics(wall_clock), + Time4 = erlang:system_time(nanosecond), NewDsF = for(Num, NewDsU), - {_, TimeF} = erlang:statistics(wall_clock), + Time5 = erlang:system_time(nanosecond), delete(Num, NewDsF), - {_, TimeD} = erlang:statistics(wall_clock), - erlang:send(Pid, {over, self(), TimeI, TimeR, TimeU, TimeF, not_support}), + Time6 = erlang:system_time(nanosecond), + erlang:send(Pid, {over, self(), Time2 - Time1, Time3 - Time2, Time4 - Time3, Time5 - Time4, not_support}), + exit(normal); +start(Num, Pid) -> + erlang:send(Pid, {over, self(), skip, skip, skip, skip, skip}), exit(normal). init(Num) -> diff --git a/src/testCase/utTestDS.erl b/src/testCase/utTestDS.erl deleted file mode 100644 index 937864a..0000000 --- a/src/testCase/utTestDS.erl +++ /dev/null @@ -1,35 +0,0 @@ --module(utTestDS). --compile([export_all, nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). - -%% 用于测试erlang各种数据结构 读写遍历等操作的效率 -%%  lists ,maps 和record是erlang最为常用的数据结构,lists使用方便简单,maps则查询高效,record则需要预定义, -%% 可扩展性差,各有各的优。本文做一下lists和maps的性能对比(再对比一下dict),代码如下(record操作不便则不做比较)。 - -%%通过注释部分代码做以下测试 -%%timer:tc(lib_test, test_struct, [10000,#{}]). -%%timer:tc(lib_test, test_struct, [10000,[]]). -test_struct(0, R) -> - Fun = fun({K, V}) -> K + 1, V + 1 end, lists:foreach(Fun, R), %%遍历测试 - Fun = fun(K, V) -> K + 1, V + 1 end, maps:map(Fun, R), - ok; -test_struct(Num, R) -> - NewR = [{Num, Num} | R], lists:keyfind(5000, 1, NewR), %%插入查询测试 - NewR = R#{Num=>Num}, maps:get(5000, NewR, 0), - test_struct(Num - 1, NewR). -%% 做10000次的插入查询测试结果: -%% -%%     lists 50736微秒 -%%     maps 4670微秒 -%%     dict 60236微秒 -%% 做10000次的遍历结果: -%% -%%     lists 523微秒 -%%     maps 8337微秒 -%%     dict 4426微秒 -%% 对比总结: -%% -%%     对比测试数据maps在查询性能上比lists高10倍以上, 而在遍历上lists则更优。对于频繁插入和查询的数据,maps是最佳的选择, -%% lists则适用于广播列表之类需要遍历的数据。除此之外,个人觉得在使用上lists 比maps更为方便,因为lists模块提供了大量实用的函数, -%% 单单在排序上,maps的实用性就不如lists了,所以在数据结构选择上就需要多多斟酌。另外record在查询上使用的是模式匹配,性能只会更高, -%% 但需要提前定义字段,可扩展性差,在热更这块有不少坑,maps也可以用模式匹配查询,但也要确保key值存在,不然就nomatch, -%% 但整体上maps更优于record,故建议用maps替代record。