If you’re trying to optimize the performance of an application, it’s helpful to take measurements. The simplest method is to track the start time and end time of a small block of code, then print the difference.
Side note: To accurately measure perfomance, you should really average the performance over a longer period of time using repeatable input in a controlled environment. The method I describe here is useful for getting rough measurements and for comparing code with vastly different performance characteristics. In other words, it’s painting in broad strokes.
In Erlang, I used to find myself doing the following:
Start = now(),
...some code...
End = now(),
DiffMS = timer:now_diff(End, Start) / 1000,
io:format("The operation took: ~p milliseconds~n", [Diff])
Needless to say, all that typing made me dread adding timing statements to code. Plus, if I wanted multiple timing statements in the same block of code I was stuck naming the variables ‘Start1’, ‘Start2’, ‘Start3’, etc.
To simplify the process, I made the following macro:
-ifndef(TIMEON).
%% Yes, these need to be on a single line to work...
-define(TIMEON, erlang:put(debug_timer, [now()|case erlang:get(debug_timer) == undefined of true -> []; false -> erlang:get(debug_timer) end])).
-define(TIMEOFF(Var), io:format("~s :: ~10.2f ms : ~p~n", [string:copies(" ", length(erlang:get(debug_timer))), (timer:now_diff(now(), hd(erlang:get(debug_timer)))/1000), Var]), erlang:put(debug_timer, tl(erlang:get(debug_timer)))).
-endif.
This allows me to write:
?TIMEON,
...some code...
?TIMEOFF(my_code_block).
Which prints:
:: 5.00ms : my_code_block
The ?TIMEON
statement works by stuffing the current time into a
queue in the process dictionary under the ‘debug_timer’ key,
initializing the queue if it is not already initialized.
The ?TIMEOFF
statement pops the first value from the
aforementioned queue and compares it to the current time, printing the
results.
You may ask, “Why all the trouble queuing the current time into a
list?” The answer is that we want the timing function to work even
when it is nested. In other words, you can put timing statement inside
another timing statement. The first ?TIMEOFF
call will print the
inner time, and the second ?TIMEOFF
call will print the outer time.
Happy Hacking!
Content © 2006-2021 Rusty Klophaus