Paul Reiners recently posted some code to the TC Lispers mailing list. The code began from Paul Graham’s ANSI Common Lisp book. Exercise 13b has you adding declarations to some code so that the compiler can better take advantage of the types involved. Oddly, the code ran more slowly with his typing than it did without it. I had the same experience when I tried this code under SBCL 1.0.23 on Mac OS X.
Here is Paul’s original code which he made available with the Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.
I stripped out the declarations and started adding them in one by one, trying to deal with as many compiler notes as I could figure out in the process. First, in the base case, the following took 22.5 seconds on my computer.
After much tweaking, I have gotten it down to just under 11 seconds. Most of that came with declaring the types of the slots in the (defstruct …)‘s and these three declarations:
(declaim (ftype (function (long-float
long-float
long-float) long-float) mag))
(declaim (ftype (function (long-float
long-float
long-float)
(values long-float
long-float
long-float)) unit-vector))
This declaration, however, shot me back up to 22 seconds.
long-float
long-float)
long-float)) minroot))
Of course, it really should have been returning (or long-float nil). But, that didn’t help either. From the compiler notes, it seems that (min …) in SBCL doesn’t deal well with unboxed floats. I will have to look harder at that section and ask on the SBCL lists. I believe that I tried decorating the expressions there, too.
(/ (the long-float (+ (the long-float (- b))
discrt)
(the long-float (* 2L0 a)))))
(the long-float
(/ (the long-float (- (the long-float (- b))
discrt)
(the long-float (* 2L0 a)))))))
The slowdown from type declarations in SBCL might come from the fact that SBCL treats type declarations as assertions and inserts code to check types. Only when (optimze (safety 0)) is declared, SBCL treats declarations as promises and removes type checking code, trusting the programmer about declarations.
From the compiler notes, it seems that (min â¦) in SBCL doesnât deal well with unboxed floats
In SBCL, all values are tagged (including floats). But 32 bits are not enough to hold tagged single-float, so effectively in many cases floats are boxed in 32-bit architectures. In 64-bit architectures, single-floats fit into 64 bits and are not boxed.
(That’s as I understand it)
I actually had safety set to 0:
(compilation-speed 0)
(safety 0)
(debug 0)))
However, adding type declarations to one of the methods still slowed things down. However, for the most part, adding type declarations sped things up.