A timing macro for Common Lisp

:: lisp, releases

For a long time I’ve used a little macro to time chunks of code to avoid an endless succession of boilerplate functions to do this. I’ve finally published the wretched thing.

If you’re writing programs where you care about performance, you often want to be able to make programatic comparisons of performance. time doesn’t do this, since it just reports things. Instead you want something that runs a bit of code a bunch of times and then returns the average time, with ‘a bunch of times’ being controllable. timing is that macro. Here is a simple example:

(defun dotimes/in-naturals-ratio (&key (iters 10000000) (tries 1000))
  (declare (type fixnum iters)
           (optimize speed))
  (/
   (timing (:n tries)
     (let ((s 0))                       ;avoid optimizing loop away
       (declare (type fixnum s))
       (dotimes (i iters s)
         (incf s))))
   (timing (:n tries)
     (let ((s 0))
       (declare (type fixnum s))
       (for ((_ (in-naturals iters t)))
         (incf s))))))

and then, for instance

> (dotimes/in-naturals-ratio)
1.0073159

All timing does is to wrap up its body into a function and then call a function which calls this function the number of times you specify and averages the time, returning that average as a float.

There are some options which let it print a progress note every given number of calls, wrap a call to time around things so you get, for instance, GC reporting, and subtract away the same number of calls to an empty function to try and account for overhead (in practice this is not very useful).

That’s all it is. It’s available in version 10 of my Lisp tools: