Timing Code Accurately

October 19th, 2008

The 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

2 Comments

  1. cfq

    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)

  2. Ates Goral

    @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.

Add a Comment