diff --git a/src/docs/erlang数据结构相关.md b/src/docs/erlang数据结构相关.md index 4b84317..19f9347 100644 --- a/src/docs/erlang数据结构相关.md +++ b/src/docs/erlang数据结构相关.md @@ -317,4 +317,7 @@ Unique Integers on a Runtime System Instance %% lists则适用于广播列表之类需要遍历的数据。除此之外,个人觉得在使用上lists 比maps更为方便,因为lists模块提供了大量实用的函数, %% 单单在排序上,maps的实用性就不如lists了,所以在数据结构选择上就需要多多斟酌。另外record在查询上使用的是模式匹配,性能只会更高, %% 但需要提前定义字段,可扩展性差,在热更这块有不少坑,maps也可以用模式匹配查询,但也要确保key值存在,不然就nomatch, - %% 但整体上maps更优于record,故建议用maps替代record。 \ No newline at end of file + %% 但整体上maps更优于record,故建议用maps替代record。 + +## 顺序 +number < atom < reference < fun < port < pid < tuple < map < nil < list < bit string \ No newline at end of file diff --git a/src/testCase/DsTest/utArrayDs.erl b/src/testCase/DsTest/utArrayDs.erl index 1ea9ec9..0750d75 100644 --- a/src/testCase/DsTest/utArrayDs.erl +++ b/src/testCase/DsTest/utArrayDs.erl @@ -23,27 +23,27 @@ init(Num) -> array:new(Num, fixed). insert(0, Ds) -> - Key = utTestDs:makeK(0), + % Key = utTestDs:makeK(0), array:set(0, utTestDs:makeV(0), Ds); insert(Num, Ds) -> - Key = utTestDs:makeK(Num), + % Key = utTestDs:makeK(Num), NewDs = array:set(Num, utTestDs:makeV(Num), Ds), insert(Num - 1, NewDs). read(0, Ds) -> - Key = utTestDs:makeK(0), + % Key = utTestDs:makeK(0), Value = array:get(0, Ds), Ds; read(Num, Ds) -> - Key = utTestDs:makeK(Num), + % Key = utTestDs:makeK(Num), Value = array:get(Num, Ds), read(Num - 1, Ds). update(0, Ds) -> - Key = utTestDs:makeK(0), + % Key = utTestDs:makeK(0), array:set(0, utTestDs:makeV2(0), Ds); update(Num, Ds) -> - Key = utTestDs:makeK(Num), + % Key = utTestDs:makeK(Num), NewDs = array:set(Num, utTestDs:makeV2(Num), Ds), update(Num - 1, NewDs). diff --git a/src/testCase/DsTest/utOrdsetsDs.erl b/src/testCase/DsTest/utOrdsetsDs.erl index e7e53c5..6e27d1d 100644 --- a/src/testCase/DsTest/utOrdsetsDs.erl +++ b/src/testCase/DsTest/utOrdsetsDs.erl @@ -29,7 +29,6 @@ insert(0, Ds) -> Ds; insert(Num, Ds) -> Key = utTestDs:makeK(Num), - Value = utTestDs:makeV(Num), NewDs = ordsets:add_element(Key, Ds), insert(Num - 1, NewDs). diff --git a/src/testCase/DsTest/utPdDs.erl b/src/testCase/DsTest/utPdDs.erl index 13268ea..cab5c55 100644 --- a/src/testCase/DsTest/utPdDs.erl +++ b/src/testCase/DsTest/utPdDs.erl @@ -8,7 +8,7 @@ start(Num, Pid) -> Time1 = erlang:system_time(nanosecond), NewDsI = insert(Num, Ds), Time2 = erlang:system_time(nanosecond), - NewDsR = read(Num, NewDsI), + NewDsR = read(Num, NewDsI, undefined), Time3 = erlang:system_time(nanosecond), NewDsU = update(Num, NewDsR), Time4 = erlang:system_time(nanosecond), @@ -30,13 +30,12 @@ insert(Num, Ds) -> erlang:put(Key, Value), insert(Num - 1, Ds). -read(0, Ds) -> +read(0, Ds, _V) -> Ds; -read(Num, Ds) -> +read(Num, Ds, _V) -> Key = utTestDs:makeK(Num), Value = erlang:get(Key), - V = if Value == 1 -> 1; true -> 2 end, - read(Num - 1, Ds). + read(Num - 1, Ds, Value). update(0, Ds) -> Ds; diff --git a/src/testCase/DsTest/utTestDs.erl b/src/testCase/DsTest/utTestDs.erl index fd4ed61..459dd4c 100644 --- a/src/testCase/DsTest/utTestDs.erl +++ b/src/testCase/DsTest/utTestDs.erl @@ -1,15 +1,28 @@ -module(utTestDs). -compile([export_all, nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). +-record(tempCnt, { + insert = [] + , read = [] + , update = [] + , for = [] + , delete = [] +}). --define(V_NUM, [8, 16, 32, 64, 128, 256, 516, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 524288, 1048576]). -%-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]). +% -define(V_NUM, [8, 16, 32, 64, 128, 256, 516, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 524288, 1048576]). +-define(V_NUM, [8, 16, 32, 64, 128, 256, 516, 1024]). +-define(DsList, [utPdDs, utArrayDs, utTupleDs, utListsDs, utMapsDs, utEtsSetDs, utEtsOrdDs, utDictDs, utGb_treesDs, utSetsDs, utGb_setsDs, utOrddictDs, utOrdsetsDs, utAtomicsDs, utPTermDs]). +-define(Cnt, 5). start() -> - %% erlang:process_flag(trap_exit, true), - io:format("Ds benchmark..."), + %%erlang:process_flag(trap_exit, true), + erlang:erase(), + %{ok, File} = file:open("log/erlang-DsBenchMark.txt", [write, append]), + %erlang:put(pd_file, File), + fileLog("Ds benchmark...", []), runDs(?DsList, ?V_NUM), - io:format("Ds benchmark...Over ~n"). + fileLog("Ds benchmark...Over calculate the AVG~n", []), + runAvg(?DsList, ?V_NUM). + %file:close(File). runDs([Ds | T], VNumList) -> printTitle(), @@ -19,22 +32,47 @@ runDs([], _VNumList) -> ok. runNum([Num | T], Ds) -> - runExe(Num, Ds), + runCnt(?Cnt, Num, Ds), runNum(T, Ds); runNum([], _Ds) -> ok. +runCnt(0, Num, Ds) -> + ok; +runCnt(Cnt, Num, Ds) -> + runExe(Num, Ds), + runCnt(Cnt - 1, Num, Ds). + runExe(Num, Ds) -> Pid = erlang:spawn_link(Ds, start, [Num, self()]), receive {over, Pid, Insert, Read, Update, For, Delete} -> + storeStatistics(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", + fileLog("~-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)]); + {'EXIT', Pid, normal} -> + ok; _ShutDown -> - io:format("Ds test shutDown ~p ~p~n", [Ds, Num]) + io:format("Ds test shutDown ~p ~p ~p ~n", [Ds, Num, _ShutDown]) end. +runAvg([Ds | T], VNumList) -> + printAvg(), + runCal(VNumList, Ds), + runAvg(T, VNumList); +runAvg([], _VNumList) -> + ok. + +runCal([Num | T], Ds) -> + #tempCnt{insert = InsertList, read = ReadList, update = UpdateList, for = ForList, delete = DeleteList} = getStatistics(Ds, Num), + {_, DsName} = lists:split(2, atom_to_list(Ds)), + fileLog("~-9.s ~8.s ~12.s ~12.s ~14.s ~12.s ~12.s~n", + [DsName, integer_to_list(Num), calcAvg(InsertList, Num), calcAvg(ReadList, Num), calcAvg(UpdateList, Num), calcAvg(ForList, Num), calcAvg(DeleteList, Num)]), + runCal(T, Ds); +runCal([], _Ds) -> + ok. + -define(S, 1000000000). -define(MS, 1000000). -define(US, 1000). @@ -60,10 +98,45 @@ calcPer(skip, _Num) -> calcPer(Time, Num) -> float_to_list(Time / Num, [{decimals, 2}, compact]) ++ "ns". +calcAvg([not_support | _], Num) -> + <<"notSupport">>; +calcAvg([skip | _], Num) -> + <<"skip">>; +calcAvg(CntList, Num) -> + %% 去掉最大值与最小值 然后求平均值 + AvgCnt = ?Cnt - 2, + SortList = lists:sort(CntList), + AvgList = lists:sublist(SortList, 2,AvgCnt), + float_to_list(lists:sum(AvgList) / AvgCnt / Num, [{decimals, 2}, compact]) ++ "ns". + +storeStatistics(Ds, Num, Insert, Read, Update, For, Delete) -> + #tempCnt{insert = InsertList, read = ReadList, update = UpdateList, for = ForList, delete = DeleteList} = + case erlang:get({Ds, Num}) of + undefined -> + #tempCnt{}; + TempCnt -> + TempCnt + end, + NewTempCnt = #tempCnt{insert = [Insert | InsertList], read = [Read | ReadList], update = [Update | UpdateList], for = [For | ForList], delete = [Delete | DeleteList]}, + erlang:put({Ds, Num}, NewTempCnt). + +getStatistics(Ds, Num) -> + erlang:get({Ds, Num}). + 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", + fileLog("~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)]]). + fileLog("~s ~n", [[$= || _ <- lists:seq(1, 145)]]). + +printAvg() -> + fileLog("~n~-9.s ~8.s ~12.s ~12.s ~14.s ~12.s ~12.s~n", + ["DsName", "V_Num", "insert/per", "read/per", "update/per", "for/per", "delete/per"]), + fileLog("~s ~n", [[$= || _ <- lists:seq(1, 85)]]). + +fileLog(Format, Args) -> + %File = erlang:get(pd_file), + io:format(Format, Args). + %io:format(File, Format, Args). makeK(N) -> case N rem 4 of @@ -72,9 +145,9 @@ makeK(N) -> 1 -> {N, <<"test-testDs">>}; 2 -> - {N, 8686}; + {N, test}; 3 -> - {N, test} + [N, test] end. makeV(N) -> diff --git a/src/testCase/DsTest/utTupleDs.erl b/src/testCase/DsTest/utTupleDs.erl index 4663e71..7c5709b 100644 --- a/src/testCase/DsTest/utTupleDs.erl +++ b/src/testCase/DsTest/utTupleDs.erl @@ -8,11 +8,11 @@ start(Num, Pid) when Num =< 65536 -> Time1 = erlang:system_time(nanosecond), NewDsI = insert(Num, Ds), Time2 = erlang:system_time(nanosecond), - NewDsR = read(Num, NewDsI), + NewDsR = read(Num, NewDsI, undefined), Time3 = erlang:system_time(nanosecond), NewDsU = update(Num, NewDsR), Time4 = erlang:system_time(nanosecond), - NewDsF = for(Num, NewDsU), + NewDsF = for(Num, NewDsU, undefined), Time5 = erlang:system_time(nanosecond), delete(Num, NewDsF), Time6 = erlang:system_time(nanosecond), @@ -28,29 +28,30 @@ init(Num) -> insert(0, Ds) -> Ds; insert(Num, Ds) -> - Key = utTestDs:makeK(Num), + % Key = utTestDs:makeK(Num), NewDs = erlang:setelement(Num, Ds, utTestDs:makeV(Num)), insert(Num - 1, NewDs). -read(0, Ds) -> +read(0, Ds, _V) -> Ds; -read(Num, Ds) -> - Key = utTestDs:makeK(Num), +read(Num, Ds, _V) -> + % Key = utTestDs:makeK(Num), Value = erlang:element(Num, Ds), - read(Num - 1, Ds). + + read(Num - 1, Ds, Value). update(0, Ds) -> Ds; update(Num, Ds) -> - Key = utTestDs:makeK(Num), + % Key = utTestDs:makeK(Num), NewDs = erlang:setelement(Num, Ds, utTestDs:makeV2(Num)), update(Num - 1, NewDs). -for(0, Ds) -> +for(0, Ds, _V) -> Ds; -for(Num, Ds) -> +for(Num, Ds, _V) -> Value = erlang:element(Num, Ds), - for(Num - 1, Ds). + for(Num - 1, Ds, Value). delete(Num, Ds) -> ok.