Timing Code Accurately
October 19th, 2008The most common approach to time a function or a segment of code is to repeat it a lot of times in a loop, measure the time the entire loop takes and then divide that number with the number of iterations. Illustrating this with JavaScript (although this method applies to all languages):
var start = new Date(); // Get current time
for (var i = 0; i < n; i++) {
myFunction();
}
var finish = new Date(): // Get current time
var ntimes = finish - start; // Elapsed time for n iterations
var once = ntimes / n; // Average time for one function call
However, this doesn't really measure just how much time n calls to myFunction took. There's also the overhead of the loop itself. What we actually end up measuring is not just the time to execute one call to myFunction but also the overhead of one iteration:
// function + overhead var ntimes = finish - start; // Elapsed time for n iterations var once = ntimes / n; // Average time for one function call + iteration
Here's a simple deviation from this approach to easily discount the loop overhead from the final measurement:
var start = new Date(); // Get current time
for (var i = 0; i < n; i++) {
myFunction();
}
var lap = new Date(): // Get current time
for (var i = 0; i < n; i++) {
myFunction();
myFunction(); // Call the function again
}
var finish = new Date(): // Get current time
// function + overhead
var elapsed1 = lap - start; // Elapsed time for n iterations
// function + function + overhead
var elapsed2 = finish - lap; // Elapsed time for n x 2 iterations
// function + function + overhead - (function + overhead)
// = function + function + overhead - function - overhead
// = function
var ntimes = elapsed2 - elapsed1; // Elapsed time for n iterations
var once = ntimes / n; // Average time for one function call
October 20th, 2008 at 7:47 am
Javascript execution time in browsers isn’t bounded only by the JS engine though. Render engine may interrupt the process if myFunction is doing any DOM modifications, which would stop the JS timer and the resultant timing values may not be accurate. If myFunction is not doing any DOM operations I’d recommend testing function optimizations under rhino, so you can be sure there are no interruptions. (I realize you may already be doing that, sorry if I’m repeating something you already know)
October 20th, 2008 at 1:34 pm
@cfq: Thanks for that insight! I used JavaScript just for illustration purposes; in order to avoid using pseudo-code that couldn’t be properly highlighted by the automatic syntax highlighter that I’m currently using. I’ve successfully used this method to do benchmarking in C++. The benchmark program would first set the process priority to high so that my measurement wouldn’t get affected by Windows doing stuff in the background.