aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib
diff options
context:
space:
mode:
authorDan Gudmundsson <[email protected]>2011-03-30 12:50:03 +0200
committerDan Gudmundsson <[email protected]>2011-05-11 16:08:18 +0200
commit1d4472c3e6bad242c04ab5925ac12b3053ece323 (patch)
treeb2e675e2395cfa8a3f1ceb86bbde235d01180797 /lib/stdlib
parent0a80859714d86191e17f84cf60833010b20655d0 (diff)
downloadotp-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.xml8
-rw-r--r--lib/stdlib/src/timer.erl25
-rw-r--r--lib/stdlib/test/timer_simple_SUITE.erl31
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),