diff options
Diffstat (limited to 'lib/hipe/tools/hipe_timer.erl')
-rw-r--r-- | lib/hipe/tools/hipe_timer.erl | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/lib/hipe/tools/hipe_timer.erl b/lib/hipe/tools/hipe_timer.erl new file mode 100644 index 0000000000..03cc358f17 --- /dev/null +++ b/lib/hipe/tools/hipe_timer.erl @@ -0,0 +1,159 @@ +%% -*- erlang-indent-level: 2 -*- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2002-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved +%% Time-stamp: <2008-04-20 14:53:36 richard> +%% ==================================================================== +%% Module : hipe_timer +%% Purpose : +%% Notes : +%% History : * 2001-03-15 Erik Johansson ([email protected]): Created. +%% ==================================================================== +%% Exports : +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +-module(hipe_timer). + +-export([tr/1, t/1, timer/1, time/1, empty_time/0]). +-export([advanced/2]). + +t(F) -> + {EWT,ERT} = empty_time(), + {WT,RT} = time(F), + {WT-EWT,(RT-ERT)/1000}. + +tr(F) -> + {EWT,ERT} = empty_time(), + {R,{WT,RT}} = timer(F), + {R,{WT-EWT,(RT-ERT)/1000}}. + +empty_time() -> + {WT1,WT2,WT3} = erlang:now(), + {A,_} = erlang:statistics(runtime), + {WT12,WT22,WT32} = erlang:now(), + {B,_} = erlang:statistics(runtime), + {(WT12-WT1)*1000000+(WT22-WT2)+(WT32-WT3)/1000000,B-A}. + +time(F) -> + {WT1,WT2,WT3} = erlang:now(), + {A,_} = erlang:statistics(runtime), + F(), + {WT12,WT22,WT32} = erlang:now(), + {B,_} = erlang:statistics(runtime), + {(WT12-WT1)*1000000+(WT22-WT2)+(WT32-WT3)/1000000,B-A}. + +timer(F) -> + {WT1,WT2,WT3} = erlang:now(), + {A,_} = erlang:statistics(runtime), + R = F(), + {WT12,WT22,WT32} = erlang:now(), + {B,_} = erlang:statistics(runtime), + {R,{(WT12-WT1)*1000000+(WT22-WT2)+(WT32-WT3)/1000000,B-A}}. + +advanced(_Fun, I) when I < 2 -> false; +advanced(Fun, Iterations) -> + R = Fun(), + Measurements = [t(Fun) || _ <- lists:seq(1, Iterations)], + {Wallclock, RunTime} = split(Measurements), + WMin = lists:min(Wallclock), + RMin = lists:min(RunTime), + WMax = lists:max(Wallclock), + RMax = lists:max(RunTime), + WMean = mean(Wallclock), + RMean = mean(RunTime), + WMedian = median(Wallclock), + RMedian = median(RunTime), + WVariance = variance(Wallclock), + RVariance = variance(RunTime), + WStddev = stddev(Wallclock), + RStddev = stddev(RunTime), + WVarCoff = 100 * WStddev / WMean, + RVarCoff = 100 * RStddev / RMean, + WSum = lists:sum(Wallclock), + RSum = lists:sum(RunTime), + [{wallclock,[{min, WMin}, + {max, WMax}, + {mean, WMean}, + {median, WMedian}, + {variance, WVariance}, + {stdev, WStddev}, + {varcoff, WVarCoff}, + {sum, WSum}, + {values, Wallclock}]}, + {runtime,[{min, RMin}, + {max, RMax}, + {mean, RMean}, + {median, RMedian}, + {variance, RVariance}, + {stdev, RStddev}, + {varcoff, RVarCoff}, + {sum, RSum}, + {values, RunTime}]}, + {iterations, Iterations}, + {result, R}]. + +split(M) -> + split(M, [], []). + +split([{W,R}|More], AccW, AccR) -> + split(More, [W|AccW], [R|AccR]); +split([], AccW, AccR) -> + {AccW, AccR}. + +mean(L) -> + mean(L, 0, 0). + +mean([V|Vs], No, Sum) -> + mean(Vs, No+1, Sum+V); +mean([], No, Sum) when No > 0 -> + Sum/No; +mean([], _No, _Sum) -> + exit(empty_list). + +median(L) -> + S = length(L), + SL = lists:sort(L), + case even(S) of + true -> + (lists:nth((S div 2), SL) + lists:nth((S div 2) + 1, SL)) / 2; + false -> + lists:nth((S div 2), SL) + end. + +even(S) -> + (S band 1) =:= 0. + +%% diffs(L, V) -> +%% [X - V || X <- L]. + +square_diffs(L, V) -> + [(X - V) * (X - V) || X <- L]. + +variance(L) -> + Mean = mean(L), + N = length(L), + if N > 1 -> + lists:sum(square_diffs(L,Mean)) / (N-1); + true -> exit('too few values') + end. + +stddev(L) -> + math:sqrt(variance(L)). |