RSS Feed

Lisp Project of the Day

com.google.base

You can support this project by donating at:

Donate using PatreonDonate using Liberapay

Or see the list of project sponsors.

com.google.baseasdfasdf-extensionperformance

Today's Common Lisp Project of the Day is a library, written by Robert Brown, one of the authors of Google's Common Lisp Style Guide.

The library I'm talking about is "com.google.base".

It contains a simple asdf extension and some helpers for code optimization.

The extension gives you the ability to tell that some ASDF system's component should be compiled with maximum speed. Also, it is able to manage how fast and unsafe this code should be when you are compiling it for development or production.

To check how it works, we create a simple system with three components each with its own compiler policies:

;; foo.asd file
  
(defsystem "foo"
  :defsystem-depends-on (#:com.google.base)
  :serial t
  :components ((:file "package")
               (:file "first")
               (:file "second")
               ;; This special component type is defined
               ;; in the com.google.base
               (:fast-unsafe-source-file "third")))

;; first.lisp
;; 
;; This is usual CL file without
;; any compiler policy.

(defparameter *first*
  (with-output-to-string (*standard-output*)
    (sb-ext:describe-compiler-policy)))


;; second.lisp
;; 
;; Here we naively change the optimization
;; settings
(declaim (optimize (debug 3)))

(defparameter *second*
  (with-output-to-string (*standard-output*)
    (sb-ext:describe-compiler-policy)))

;; third.lisp
;;
;; Here we do nothing with optimization,
;; but in asd file this component is marked
;; as :fast-unsafe-source-file

(defparameter *third*
  (with-output-to-string (*standard-output*)
    (sb-ext:describe-compiler-policy)))

My default compiler policy is:

POFTHEDAY> (sb-ext:describe-compiler-policy)
  Basic qualities:
COMPILATION-SPEED = 1
DEBUG = 1
SAFETY = 1
SPACE = 1
SPEED = 1

And here what I've got after "foo" compilation:

POFTHEDAY> foo::*first*
"  Basic qualities:
COMPILATION-SPEED = 1
DEBUG = 1
SAFETY = 1
SPACE = 1
SPEED = 1
...
"

POFTHEDAY> foo::*second*
"  Basic qualities:
COMPILATION-SPEED = 1
DEBUG = 3
SAFETY = 1
SPACE = 1
SPEED = 1
..."

POFTHEDAY> foo::*third*
"  Basic qualities:
COMPILATION-SPEED = 0
DEBUG = 2
SAFETY = 0
SPACE = 1
SPEED = 3
..."

POFTHEDAY> com.google.base:*optimize-fast-unsafe*
(OPTIMIZE (COMPILATION-SPEED 0) (DEBUG 2)
          (SAFETY 0) (SPACE 1) (SPEED 3))

As you can see, the first component retained the default policy. The second component changed only "debug" policy to 3 and third component's policy is equal to the policy defined in com.google.base:*optimize-fast-unsafe*.

But what if for development environment we want to change a compilation policy for all performance-critical parts of the system?

With "com.google.base" this is an easy task:

POFTHEDAY> (let ((com.google.base:*optimize-fast-unsafe*
                   '(optimize
                     (compilation-speed 0) (debug 3)
                     (safety 3) (space 1) (speed 1))))
               (asdf:load-system :foo :force t))

POFTHEDAY> foo::*third*
"  Basic qualities:
COMPILATION-SPEED = 0
DEBUG = 3
SAFETY = 3
SPACE = 1
SPEED = 1
..."

Robert Brown uses this trick for many of his systems where some components should have high compiler optimization settings:

Also "google.com.base" contains a few type declarations and helpers for working with vectors.


Brought to you by 40Ants under Creative Commons License