From 1d4472c3e6bad242c04ab5925ac12b3053ece323 Mon Sep 17 00:00:00 2001 From: Dan Gudmundsson Date: Wed, 30 Mar 2011 12:50:03 +0200 Subject: 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. --- lib/stdlib/doc/src/timer.xml | 8 +++++++- lib/stdlib/src/timer.erl | 25 +++++++++++++++++-------- lib/stdlib/test/timer_simple_SUITE.erl | 31 +++++++++++++++++++++++++++++-- 3 files changed, 53 insertions(+), 11 deletions(-) (limited to 'lib/stdlib') 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 @@ tc(Module, Function, Arguments) -> {Time, Value} tc(Fun, Arguments) -> {Time, Value} + tc(Fun) -> {Time, Value} Measure the real time it takes to evaluate apply(Module, Function, Arguments) or apply(Fun, Arguments) @@ -218,7 +219,7 @@ tc/3

Evaluates apply(Module, Function, Arguments) and measures - the elapsed real time as reported by now/0. + the elapsed real time as reported by os:timestamp/0. Returns {Time, Value}, where Time is the elapsed real time in microseconds, and Value is what is returned from the apply.

@@ -228,6 +229,11 @@

Evaluates apply(Fun, Arguments). Otherwise works like tc/3.

+ tc/1 + +

Evaluates Fun(). Otherwise works like tc/2.

+
+
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), -- cgit v1.2.3