Today’s Erlang Thursday is on timer:tc/3.

I am sure we have all written some timing code where we capture the current time, do something, capture the current time again and then find the difference to find out how long something took to execute. In Erlang, that generally looks something like the following:

Time1 = now(). % {1420,519186,111375} timer:sleep(4000). % Do something % ok Time2 = now(). % {1420,519190,118280} timer:now_diff(Time2, Time1). % 4006905

Note that we have to use timer:now_diff/2, since the now() function returns the timestamp as a tuple, and we can’t just do normal subtraction on that tuple like we might be able to in other languages.

Of course as good “engineers”, we know that since we need to do timings in various places of the app we can just create our own function to do that, and have that live in just one place.

The downside is: the wise people on the Erlang language team have done that for us already and provided it in the form of timer:tc/3 .

timer:tc/3 takes the module name, function name, and a list of the arguments to be passed to the function. And since we usually want the result of the function we are calling, in addition to the timing, the return value is a tuple of the time in microseconds, and the result of applying the function passed to timer:tc/3 .

timer:tc(timer, sleep, [4000]). % {4003097,ok} timer:tc(lists, foldl, [fun(X, Accum) -> X + Accum end, 0, lists:seq(1, 2000000)]). % {5099481,2000001000000}

There is also timer:tc/1 which takes just a function and applies it, and timer:tc/2 which takes a function and applies it with the given arguments.

timer:tc(fun() -> lists:foldl(fun(X, Accum) -> X + Accum end, 0, lists:seq(1, 2000000)) end). % {5709293,2000001000000} timer:tc(fun lists:foldl/3, [fun(X, Accum) -> X + Accum end, 0, lists:seq(1, 2000000)]). % {5766480,2000001000000}

–Proctor