源战役
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

78 lines
2.6 KiB

%%% -------------------------------------------------------
%%% @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.