|
|
- %%% -------------------------------------------------------
- %%% @author huangyongxing@yeah.net
- %%% @doc
- %%% 简单的性能测试工具,匿名函数的影响有限,
- %%% 但是方便不修改工具直接外部添加测试用例进行对比使用,
- %%% 所以忽略匿名函数对测试结果的影响,做基本的性能判断
- %%%
- %%% 对比测试方式:
- %%% ptester:run(Times, [
- %%% {Fun1Label, Fun1/1},
- %%% {Fun2Label, Fun2/1},
- %%% ...
- %%% ]).
- %%% 单个函数测试:
- %%% ptester:timer(FunLabel, Fun/1, Times).
- %%% @end
- %%% -------------------------------------------------------
- -module(ptester).
- -compile(export_all).
-
- %% 运行一个测试集
- run(N, List) ->
- [[L, T1, T2] = H | T] = [timer(Label, F, N) || {Label, F} <- List],
- io:format("========================================================================~n"),
- io:format("~20s = ~9.2fms [~8.2f%] ~9.2fms [~8.2f%]~n", [L, T1 + 0.0, 100.0, T2 + 0.0, 100.0]),
- compare(T, H),
- io:format("========================================================================~n").
-
- %% 运行单项测试并计时
- timer(Label, F, N) ->
- % WordSize = erlang:system_info(wordsize),
- % 分配较大的初始空间,减少gc对测试结果的影响,以期获得更准确的结果
- % MinHeapSize = 20 * 1024 * 1024,
- % MinBinVHeapSize = MinHeapSize,
- % erlang:process_flag(min_heap_size, MinHeapSize),
- % erlang:process_flag(min_bin_vheap_size, MinBinVHeapSize),
- % 先进行gc一次,避免多个函数测试时,上一次的测试对进程gc的相关影响
- erlang:garbage_collect(self()),
- statistics(runtime),
- statistics(wall_clock),
- for(1, N, F),
- {_, Time1} = statistics(runtime),
- {_, Time2} = statistics(wall_clock),
- U1 = Time1 * 1000 / N,
- U2 = Time2 * 1000 / N,
- io:format("~p [total: ~p(~p)ms avg: ~.3f(~.3f)us]~n", [Label, Time1, Time2, U1, U2]),
- [Label, Time1, Time2].
-
- %% 比较结果
- compare([], _) ->
- ok;
- compare([[L, T1, T2] | T], [_, TB1, TB2] = TB) ->
- io:format(
- "~20s = ~9.2fms [~8.2f%] ~9.2fms [~8.2f%]~n",
- [L, T1 + 0.0, T1 / (TB1 + 0.00000001) * 100, T2 + 0.0, T2 / (TB2 + 0.00000001) * 100]
- ),
- compare(T, TB).
-
- %% for循环
- for(Max, Max, F) -> F(Max);
- for(I, Max, F) -> F(I), for(I + 1, Max, F).
-
- %% 产生随机数
- rand(Same, Same) -> Same;
- rand(Min, Max) when Max < Min ->
- rand(Max, Min);
- rand(Min, Max) ->
- case get("rand_seed") of
- undefined ->
- RandSeed = os:timestamp(),
- rand:seed(RandSeed),
- put("rand_seed", RandSeed);
- _ ->
- skip
- end,
- M = Min - 1,
- rand:uniform(Max - M) + M.
-
|