diff options
author | Dan Gudmundsson <[email protected]> | 2011-03-30 12:50:03 +0200 |
---|---|---|
committer | Dan Gudmundsson <[email protected]> | 2011-05-11 16:08:18 +0200 |
commit | 1d4472c3e6bad242c04ab5925ac12b3053ece323 (patch) | |
tree | b2e675e2395cfa8a3f1ceb86bbde235d01180797 /lib/stdlib | |
parent | 0a80859714d86191e17f84cf60833010b20655d0 (diff) | |
download | otp-1d4472c3e6bad242c04ab5925ac12b3053ece323.tar.gz otp-1d4472c3e6bad242c04ab5925ac12b3053ece323.tar.bz2 otp-1d4472c3e6bad242c04ab5925ac12b3053ece323.zip |
Add timer:tc/1 which measures elapsed time for a fun/0
Also removes the 'catch' from timer:tc functions which masked errors
in measuring code.
Diffstat (limited to 'lib/stdlib')
-rw-r--r-- | lib/stdlib/doc/src/timer.xml | 8 | ||||
-rw-r--r-- | lib/stdlib/src/timer.erl | 25 | ||||
-rw-r--r-- | lib/stdlib/test/timer_simple_SUITE.erl | 31 |
3 files changed, 53 insertions, 11 deletions
diff --git a/lib/stdlib/doc/src/timer.xml b/lib/stdlib/doc/src/timer.xml index cae655f801..0baeff1db3 100644 --- a/lib/stdlib/doc/src/timer.xml +++ b/lib/stdlib/doc/src/timer.xml @@ -203,6 +203,7 @@ <func> <name>tc(Module, Function, Arguments) -> {Time, Value}</name> <name>tc(Fun, Arguments) -> {Time, Value}</name> + <name>tc(Fun) -> {Time, Value}</name> <fsummary>Measure the real time it takes to evaluate <c>apply(Module, Function, Arguments)</c> or <c>apply(Fun, Arguments)</c></fsummary> <type> @@ -218,7 +219,7 @@ <tag><c>tc/3</c></tag> <item> <p>Evaluates <c>apply(Module, Function, Arguments)</c> and measures - the elapsed real time as reported by <c>now/0</c>. + the elapsed real time as reported by <c>os:timestamp/0</c>. Returns <c>{Time, Value}</c>, where <c>Time</c> is the elapsed real time in <em>microseconds</em>, and <c>Value</c> is what is returned from the apply.</p> @@ -228,6 +229,11 @@ <p>Evaluates <c>apply(Fun, Arguments)</c>. Otherwise works like <c>tc/3</c>.</p> </item> + <tag><c>tc/1</c></tag> + <item> + <p>Evaluates <c>Fun()</c>. Otherwise works like <c>tc/2</c>.</p> + </item> + </taglist> </desc> </func> diff --git a/lib/stdlib/src/timer.erl b/lib/stdlib/src/timer.erl index b456c5d6c1..78e897b877 100644 --- a/lib/stdlib/src/timer.erl +++ b/lib/stdlib/src/timer.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% Copyright Ericsson AB 1996-2011. 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 @@ -22,7 +22,7 @@ send_after/3, send_after/2, exit_after/3, exit_after/2, kill_after/2, kill_after/1, apply_interval/4, send_interval/3, send_interval/2, - cancel/1, sleep/1, tc/2, tc/3, now_diff/2, + cancel/1, sleep/1, tc/1, tc/2, tc/3, now_diff/2, seconds/1, minutes/1, hours/1, hms/3]). -export([start_link/0, start/0, @@ -101,15 +101,24 @@ sleep(T) -> after T -> ok end. +%% +%% Measure the execution time (in microseconds) for Fun(). +%% +-spec tc(function()) -> {time(), term()}. +tc(F) -> + Before = os:timestamp(), + Val = F(), + After = os:timestamp(), + {now_diff(After, Before), Val}. %% %% Measure the execution time (in microseconds) for Fun(Args). %% -spec tc(function(), [_]) -> {time(), term()}. tc(F, A) -> - Before = erlang:now(), - Val = (catch apply(F, A)), - After = erlang:now(), + Before = os:timestamp(), + Val = apply(F, A), + After = os:timestamp(), {now_diff(After, Before), Val}. %% @@ -117,9 +126,9 @@ tc(F, A) -> %% -spec tc(atom(), atom(), [term()]) -> {time(), term()}. tc(M, F, A) -> - Before = erlang:now(), - Val = (catch apply(M, F, A)), - After = erlang:now(), + Before = os:timestamp(), + Val = apply(M, F, A), + After = os:timestamp(), {now_diff(After, Before), Val}. %% diff --git a/lib/stdlib/test/timer_simple_SUITE.erl b/lib/stdlib/test/timer_simple_SUITE.erl index 852afa1a4d..dc751aad16 100644 --- a/lib/stdlib/test/timer_simple_SUITE.erl +++ b/lib/stdlib/test/timer_simple_SUITE.erl @@ -229,7 +229,7 @@ cancel2(Config) when is_list(Config) -> tc(doc) -> "Test sleep/1 and tc/3."; tc(suite) -> []; tc(Config) when is_list(Config) -> - % This should both sleep and tc/3 + %% This should test both sleep and tc/3 ?line {Res1, ok} = timer:tc(timer, sleep, [500]), ?line ok = if Res1 < 500*1000 -> {too_early, Res1}; % Too early @@ -237,13 +237,40 @@ tc(Config) when is_list(Config) -> true -> ok end, - % This should both sleep and tc/2 + %% tc/2 ?line {Res2, ok} = timer:tc(fun(T) -> timer:sleep(T) end, [500]), ?line ok = if Res2 < 500*1000 -> {too_early, Res2}; % Too early Res2 > 800*1000 -> {too_late, Res2}; % Too much time true -> ok end, + + %% tc/1 + ?line {Res3, ok} = timer:tc(fun() -> timer:sleep(500) end), + ?line ok = if + Res3 < 500*1000 -> {too_early, Res3}; % Too early + Res3 > 800*1000 -> {too_late, Res3}; % Too much time + true -> ok + end, + + %% Check that timer:tc don't catch errors + ?line ok = try timer:tc(erlang, exit, [foo]) + catch exit:foo -> ok + end, + + ?line ok = try timer:tc(fun(Reason) -> 1 = Reason end, [foo]) + catch error:{badmatch,_} -> ok + end, + + ?line ok = try timer:tc(fun() -> throw(foo) end) + catch foo -> ok + end, + + %% Check that return values are propageted + Self = self(), + ?line {_, Self} = timer:tc(erlang, self, []), + ?line {_, Self} = timer:tc(fun(P) -> P end, [self()]), + ?line {_, Self} = timer:tc(fun() -> self() end), ?line Sec = timer:seconds(4), ?line Min = timer:minutes(4), |