aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/tools/hipe_timer.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hipe/tools/hipe_timer.erl')
-rw-r--r--lib/hipe/tools/hipe_timer.erl159
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)).