diff --git a/src/docs/erlang数据结构相关.md b/src/docs/erlang数据结构相关.md index 19f9347..4dd5336 100644 --- a/src/docs/erlang数据结构相关.md +++ b/src/docs/erlang数据结构相关.md @@ -194,14 +194,6 @@ Unique Integers on a Runtime System Instance years. That is, for the foreseeable future they are unique enough. ``` - -# Erlang标准数据结构的选择 - 实际上,Erlang程序使用列表(本机或通过dict)来处理涉及多达数百个元素的数据结构,并使用ETS(Erlang术语存储)或mnesia来处理更大的数据。 - ETS使用散列来允许几乎恒定时间访问几乎任意数量的数据。 - 对于由几个(几十个或几百个)项组成的数据集合,列表通常要优于ETS和树。 对于大量小物品,ETS往往效果最好。 对于较大的项目,平衡树可以胜过ETS,因为它们避免了复制数据。 - Suggestion: - elments count: 0 - 100 | 100 - 10000 | 10000 - - our select : list | ets | gb_tree # Erlang 常用数据结构实现 erlang虚拟机中用Eterm表示所有的类型的数据,具体的实施方案通过占用Eterm的后几位作为类型标签,然后根据标签类型来解释剩余位的用途。这个标签是多层级的,最外层占用两位,有三种类型: @@ -279,45 +271,30 @@ Unique Integers on a Runtime System Instance 在实现上,array最外层被包装为一个record: ... 其他等待被添加 - %% Module Description - %% sets sets, a collection of unique elements. - %% gb_sets sets, but based on a general balanced data structure - %% gb_tree a general balanced tree - %% dict maps, also called associative arrays - %% queue double-ended queues - %% ets hash tables and ordered sets (trees), stored outside the process - %% dets on-disk hash tables - (请注意:不常用的模块ordset和 orddict只是有序列表,因此对于诸如插入之类的常见操作具有O(n)) - % Suggestion: - % elments count: 0 - 100 | 100 - 10000 | 10000 - - % 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。 - ## 顺序 -number < atom < reference < fun < port < pid < tuple < map < nil < list < bit string \ No newline at end of file +number < atom < reference < fun < port < pid < tuple < map < nil < list < bit string + %% Module Description + %% sets sets, a collection of unique elements. + %% gb_sets sets, but based on a general balanced data structure + %% gb_tree a general balanced tree + %% dict maps, also called associative arrays + %% queue double-ended queues + %% ets hash tables and ordered sets (trees), stored outside the process + %% dets on-disk hash tables + (请注意:不常用的模块ordset和 orddict只是有序列表,因此对于诸如插入之类的常见操作具有O(n)) + +# Erlang标准数据结构的选择 + 实际上,Erlang程序使用列表(本机或通过dict)来处理涉及多达数百个元素的数据结构, + 并使用ETS(Erlang术语存储)或mnesia来处理更大的数据。 + ETS使用散列来允许几乎恒定时间访问几乎任意数量的数据。 + 对于由几个(几十个或几百个)项组成的数据集合,列表通常要优于ETS和树。 对于大量小物品,ETS往往效果最好。 + 对于较大的项目,数据插入ets和从ets读取都会复制数据, 需要掂量。 + + lists ,maps 和record是erlang最为常用的数据结构,lists使用方便简单,maps则查询高效,record则需要预定义, + 对比测试数据maps在查询性能上比lists高, 而在遍历上lists则更优。对于频繁插入和查询的数据,maps是最佳的选择, + record在数据量小的情况下 插入 更新 查询效率都很高, 而且使用的是模式匹配也很方便 + lists则适用于广播列表之类需要遍历的数据和数据量少的情况。 + 更多数据结构 + utPdDs, utArrayDs, utTupleDs, utListsDs, utMapsDs, utEtsSetDs, utEtsOrdDs, utDictDs, utGb_treesDs, utSetsDs, utGb_setsDs, utOrddictDs, utOrdsetsDs, utAtomicsDs, utPTermDs + 测试代码见 testCase/DsTest + 数据结构测评结果见 dosc/erlang-DsBenchMark.txt \ No newline at end of file diff --git a/src/dsInterface/utArray.erl b/src/dsInterface/utArray.erl new file mode 100644 index 0000000..1c8a873 --- /dev/null +++ b/src/dsInterface/utArray.erl @@ -0,0 +1,32 @@ +-module(utArray). + +%% 基于tuple封装的数组 +%% 基于性能测试结果和出于性能考虑数组大小不要超过128 +-import(erlang, [make_tuple/2, make_tuple/3]). +-export([ + new/1 + , new/2 + , new/3 + , set/3 + , get/2 + , size/1 +]). + +new(Size) -> + erlang:make_tuple(Size, undefined). + +new(Size, InitialValue) -> + erlang:make_tuple(Size, InitialValue). + +new(Size, DefaultValue, InitList) -> + erlang:make_tuple(Size, DefaultValue, InitList). + +set(Idx, Value, UtArray) -> + erlang:setelement(Idx, UtArray, Value). + +get(Idx, UtArray) -> + erlang:element(Idx, UtArray). + +size(UtArray) -> + erlang:tuple_size(UtArray). + diff --git a/src/dsInterface/utHashBbl.erl b/src/dsInterface/utHashBbl.erl new file mode 100644 index 0000000..1bb6e1c --- /dev/null +++ b/src/dsInterface/utHashBbl.erl @@ -0,0 +1,53 @@ +-module(utHashBbl). +-import(erlang, [make_tuple/2, make_tuple/3]). +-compile([export_all, nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). + +-define(Solt_1, 128). +-define(Solt_2, 128). + +new() -> + erlang:make_tuple(?Solt_1, erlang:make_tuple(?Solt_2, undefined)). + +put(Key, Value, HashBbl1) -> + BblNum1 = erlang:phash2(Key, ?Solt_1) + 1, + BblNum2 = erlang:phash(Key, ?Solt_2), + HashBbl2 = erlang:element(BblNum1, HashBbl1), + ValueList = erlang:element(BblNum2, HashBbl2), + case ValueList of + undefined -> + erlang:setelement(BblNum1, HashBbl1, erlang:setelement(BblNum2, HashBbl2, {Key, Value})); + {Key, Value} -> + HashBbl1; + {Key, _OldValue} -> + erlang:setelement(BblNum1, HashBbl1, erlang:setelement(BblNum2, HashBbl2, {Key, Value})); + {_OldKey, _OldValue} = OldInfo -> + erlang:setelement(BblNum1, HashBbl1, erlang:setelement(BblNum2, HashBbl2, [{Key, Value}, OldInfo])); + List -> + case lists:keyfind(Key, 1, List) of + false -> + erlang:setelement(BblNum1, HashBbl1, erlang:setelement(BblNum2, HashBbl2, [{Key, Value} | List])); + {Key, Value} -> + HashBbl1; + {Key, _OldValue} -> + erlang:setelement(BblNum1, HashBbl1, erlang:setelement(BblNum2, HashBbl2, lists:keyreplace(Key, 1, List, {Key, Value}))) + end + end. + +get(Key, HashBbl1) -> + BblNum1 = erlang:phash2(Key, ?Solt_1) + 1, + BblNum2 = erlang:phash(Key, ?Solt_2), + HashBbl2 = erlang:element(BblNum1, HashBbl1), + ValueList = erlang:element(BblNum2, HashBbl2), + case ValueList of + undefined -> + undefined; + {Key, Value} -> + Value; + List -> + case lists:keyfind(Key, 1, List) of + false -> + undefined; + {Key, Value} -> + Value + end + end. diff --git a/src/dsInterface/utHashBbl1.erl b/src/dsInterface/utHashBbl1.erl new file mode 100644 index 0000000..97c6c7b --- /dev/null +++ b/src/dsInterface/utHashBbl1.erl @@ -0,0 +1,57 @@ +-module(utHashBbl1). +-import(erlang, [make_tuple/2, make_tuple/3]). +-compile([export_all, nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). + +-define(Solt_1, 128). +-define(Solt_2, 128). + +new() -> + erlang:make_tuple(?Solt_1, []). + +put(Key, Value, HashBbl1) -> + BblNum1 = erlang:phash2(Key, ?Solt_1) + 1, + BblNum2 = erlang:phash(Key, ?Solt_2), + HashBbl2 = erlang:element(BblNum1, HashBbl1), + case lists:keyfind(BblNum2, 1, HashBbl2) of + false -> + erlang:setelement(BblNum1, HashBbl1, [{BblNum2, {Key, Value}} | HashBbl2]); + {BblNum2, ValueList} -> + case ValueList of + {Key, Value} -> + HashBbl1; + {Key, _OldValue} -> + erlang:setelement(BblNum1, HashBbl1, lists:keyreplace(BblNum2, 1, HashBbl2, {BblNum2, {Key, Value}})); + {_OldKey, _OldValue} = OldInfo -> + erlang:setelement(BblNum1, HashBbl1, lists:keyreplace(BblNum2, 1, HashBbl2, {BblNum2, [{Key, Value}, OldInfo]})); + List -> + case lists:keyfind(Key, 1, List) of + false -> + erlang:setelement(BblNum1, HashBbl1, lists:keyreplace(BblNum2, 1, HashBbl2, {BblNum2, [{Key, Value} | List]})); + {Key, Value} -> + HashBbl1; + {Key, _OldValue} -> + erlang:setelement(BblNum1, HashBbl1, lists:keyreplace(BblNum2, 1, HashBbl2, {BblNum2, lists:keyreplace(Key, 1, List, {Key, Value})})) + end + end + end. + +get(Key, HashBbl1) -> + BblNum1 = erlang:phash2(Key, ?Solt_1) + 1, + BblNum2 = erlang:phash(Key, ?Solt_2), + HashBbl2 = erlang:element(BblNum1, HashBbl1), + case lists:keyfind(BblNum2, 1, HashBbl2) of + false -> + undefined; + {BblNum2, ValueList} -> + case ValueList of + {Key, Value} -> + Value; + List -> + case lists:keyfind(Key, 1, List) of + false -> + undefined; + {Key, Value} -> + Value + end + end + end. diff --git a/src/testCase/DsTest/utArrayDs1.erl b/src/testCase/DsTest/utArrayDs1.erl new file mode 100644 index 0000000..546d541 --- /dev/null +++ b/src/testCase/DsTest/utArrayDs1.erl @@ -0,0 +1,55 @@ +-module(utArrayDs1). +-compile([nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). + +-export([start/2]). + +start(Num, Pid) when Num =< 8192 -> + Ds = init(Num), + Time1 = erlang:system_time(nanosecond), + NewDsI = insert(Num, Ds), + 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(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, not_support}), + exit(normal); +start(Num, Pid) -> + erlang:send(Pid, {over, self(), skip, skip, skip, skip, skip}), + exit(normal). + +init(Num) -> + utArray:new(Num). + +insert(0, Ds) -> + Ds; +insert(Num, Ds) -> + % Key = utTestDs:makeK(Num), + NewDs = utArray:set(Num, utTestDs:makeV(Num), Ds), + insert(Num - 1, NewDs). + +read(0, Ds) -> + Ds; +read(Num, Ds) -> + % Key = utTestDs:makeK(Num), + Value = utArray:get(Num, Ds), + read(Num - 1, Ds). + +update(0, Ds) -> + Ds; +update(Num, Ds) -> + NewDs = utArray:set(Num, utTestDs:makeV2(Num), Ds), + update(Num - 1, NewDs). + + +for(Num, Ds) -> + Ds. + +delete(Num, Ds) -> + ok. + + diff --git a/src/testCase/DsTest/utHashBblDs.erl b/src/testCase/DsTest/utHashBblDs.erl new file mode 100644 index 0000000..e7c15ae --- /dev/null +++ b/src/testCase/DsTest/utHashBblDs.erl @@ -0,0 +1,57 @@ +-module(utHashBblDs). +-compile([nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). + +-export([start/2]). + +start(Num, Pid) when Num =< 65536 -> + Ds = init(Num), + Time1 = erlang:system_time(nanosecond), + NewDsI = insert(Num, Ds), + Time2 = erlang:system_time(nanosecond), + NewDsR = read(Num, NewDsI, undefined), + 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, 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) -> + utHashBbl:new(). + +insert(0, Ds) -> + Ds; +insert(Num, Ds) -> + Key = utTestDs:makeK(Num), + Value = utTestDs:makeV(Num), + NewDs = utHashBbl:put(Key, Value, Ds), + insert(Num - 1, NewDs). + +read(0, Ds, _V) -> + Ds; +read(Num, Ds, _V) -> + Key = utTestDs:makeK(Num), + Value = utHashBbl:get(Key, Ds), + read(Num - 1, Ds, Value). + +update(0, Ds) -> + Ds; +update(Num, Ds) -> + Key = utTestDs:makeK(Num), + Value = utTestDs:makeV2(Num), + NewDs = utHashBbl:put(Key, Value, Ds), + update(Num - 1, NewDs). + +for(Num, Ds) -> + Ds. + +delete(Num, Ds) -> + ok. + + diff --git a/src/testCase/DsTest/utHashBblDs1.erl b/src/testCase/DsTest/utHashBblDs1.erl new file mode 100644 index 0000000..ec904af --- /dev/null +++ b/src/testCase/DsTest/utHashBblDs1.erl @@ -0,0 +1,58 @@ +-module(utHashBblDs1). +-compile([nowarn_unused_function, nowarn_unused_vars, nowarn_export_all]). + +-export([start/2]). + +start(Num, Pid) when Num =< 65536 -> + Ds = init(Num), + Time1 = erlang:system_time(nanosecond), + NewDsI = insert(Num, Ds), + Time2 = erlang:system_time(nanosecond), + NewDsR = read(Num, NewDsI, undefined), + 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, Time4 - Time3, Time5 - Time4, not_support}), + %io:format("~w",[NewDsF]), + exit(normal); +start(Num, Pid) -> + erlang:send(Pid, {over, self(), skip, skip, skip, skip, skip}), + exit(normal). + +init(Num) -> + utHashBbl1:new(). + +insert(0, Ds) -> + Ds; +insert(Num, Ds) -> + Key = utTestDs:makeK(Num), + Value = utTestDs:makeV(Num), + NewDs = utHashBbl1:put(Key, Value, Ds), + insert(Num - 1, NewDs). + +read(0, Ds, _V) -> + Ds; +read(Num, Ds, _V) -> + Key = utTestDs:makeK(Num), + Value = utHashBbl1:get(Key, Ds), + read(Num - 1, Ds, Value). + +update(0, Ds) -> + Ds; +update(Num, Ds) -> + Key = utTestDs:makeK(Num), + Value = utTestDs:makeV2(Num), + NewDs = utHashBbl1:put(Key, Value, Ds), + update(Num - 1, NewDs). + +for(Num, Ds) -> + Ds. + +delete(Num, Ds) -> + ok. + + diff --git a/src/testCase/DsTest/utTestDs.erl b/src/testCase/DsTest/utTestDs.erl index 459dd4c..379dbf7 100644 --- a/src/testCase/DsTest/utTestDs.erl +++ b/src/testCase/DsTest/utTestDs.erl @@ -8,21 +8,23 @@ , 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, [utPdDs, utArrayDs, utTupleDs, utListsDs, utMapsDs, utEtsSetDs, utEtsOrdDs, utDictDs, utGb_treesDs, utSetsDs, utGb_setsDs, utOrddictDs, utOrdsetsDs, utAtomicsDs, utPTermDs]). --define(Cnt, 5). +%-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, 2048, 4096, 8192, 16384, 32768]). +-define(DsList, [utPdDs, utArrayDs, utTupleDs, utListsDs, utMapsDs, utEtsSetDs, utEtsOrdDs, utDictDs, utGb_treesDs, utSetsDs, utGb_setsDs, utOrddictDs, utOrdsetsDs, utAtomicsDs, utPTermDs, utArrayDs1, utHashBblDs, utHashBblDs1]). +%-define(DsList, [utPdDs, utArrayDs, utTupleDs, utListsDs, utMapsDs, utEtsSetDs, utArrayDs1, utHashBblDs, utHashBblDs1]). +%-define(DsList, [utMapsDs, utArrayDs1, utHashBblDs]). + +-define(Cnt, 12). start() -> %%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...", []), + printLog("Ds benchmark...", []), + runDs(?DsList, ?V_NUM), - fileLog("Ds benchmark...Over calculate the AVG~n", []), + printLog("Ds benchmark...Over calculate the AVG~n", []), runAvg(?DsList, ?V_NUM). - %file:close(File). + runDs([Ds | T], VNumList) -> printTitle(), @@ -49,7 +51,7 @@ runExe(Num, Ds) -> {over, Pid, Insert, Read, Update, For, Delete} -> storeStatistics(Ds, Num, Insert, Read, Update, For, Delete), {_, DsName} = lists:split(2, atom_to_list(Ds)), - 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", + printLog("~-10.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; @@ -67,7 +69,7 @@ runAvg([], _VNumList) -> 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", + printLog("~-10.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) -> @@ -83,11 +85,11 @@ timeToStr(not_support) -> timeToStr(skip) -> <<"skip">>; timeToStr(Time) when Time > ?S -> - float_to_list(Time / ?S, [{decimals, 2}, compact]) ++ "s"; + float_to_list(Time / ?S, [{decimals, 2}]) ++ "s"; timeToStr(Time) when Time > ?MS -> - float_to_list(Time / ?MS, [{decimals, 2}, compact]) ++ "ms"; + float_to_list(Time / ?MS, [{decimals, 2}]) ++ "ms"; timeToStr(Time) when Time > ?US -> - float_to_list(Time / ?US, [{decimals, 2}, compact]) ++ "us"; + float_to_list(Time / ?US, [{decimals, 2}]) ++ "us"; timeToStr(Time) -> integer_to_list(Time) ++ "ns". @@ -96,7 +98,7 @@ calcPer(not_support, _Num) -> calcPer(skip, _Num) -> <<"skip">>; calcPer(Time, Num) -> - float_to_list(Time / Num, [{decimals, 2}, compact]) ++ "ns". + float_to_list(Time / Num, [{decimals, 2}]) ++ "ns". calcAvg([not_support | _], Num) -> <<"notSupport">>; @@ -107,7 +109,7 @@ 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". + float_to_list(lists:sum(AvgList) / AvgCnt / Num, [{decimals, 2}]) ++ "ns". storeStatistics(Ds, Num, Insert, Read, Update, For, Delete) -> #tempCnt{insert = InsertList, read = ReadList, update = UpdateList, for = ForList, delete = DeleteList} = @@ -124,19 +126,21 @@ getStatistics(Ds, Num) -> erlang:get({Ds, Num}). printTitle() -> - 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", + printLog("~n~-10.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"]), - fileLog("~s ~n", [[$= || _ <- lists:seq(1, 145)]]). + printLog("~s ~n", [[$= || _ <- lists:seq(1, 145)]]). printAvg() -> - fileLog("~n~-9.s ~8.s ~12.s ~12.s ~14.s ~12.s ~12.s~n", + printLog("~n~-10.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)]]). + printLog("~s ~n", [[$= || _ <- lists:seq(1, 85)]]). -fileLog(Format, Args) -> - %File = erlang:get(pd_file), +printLog(Format, Args) -> + % {ok, File} = file:open("src/docs/erlang-DsBenchMark.txt", [write, append]), + % io:format(File, Format, Args), + % file:close(File). io:format(Format, Args). - %io:format(File, Format, Args). + makeK(N) -> case N rem 4 of diff --git a/src/testCase/utTestPerformance.erl b/src/testCase/utTestPerformance.erl index 70b4b29..1f56e5e 100644 --- a/src/testCase/utTestPerformance.erl +++ b/src/testCase/utTestPerformance.erl @@ -222,4 +222,18 @@ getMonth3(Month) -> <<"">> end. +-define(List, [1, 2, 3234235, <<"fdsfasf">>, <<"fdsfasf111111111111111111111111">>, [3434,43,434], tryrer, {rqwrer, 342144}, #{23424 => "fdsfsdafsaf"}, {432143, "fdsaf", 76767}]). + +ht(0, _Fun) -> + ok; +ht(N, Fun) -> + [?MODULE:Fun(Term) || Term <- ?List], + ht(N - 1, Fun). + +hash1(Term) -> + erlang:phash(Term, 256). + +hash2(Term) -> + erlang:phash2(Term, 256). +