Structure slot accessors are efficient only if the compiler is able to
open code them: compiling a call to a structure slot accessor before
the structure is defined, declaring one
notinline, or passing
it as a functional argument to another function causes severe
The most efficient way to access a slot of a
slot-value with a constant slot name argument inside a
defmethod body, where the variable holding the instance is a
specializer parameter of the method and is never assigned to. The cost
is roughly 1.6 times that of an open coded structure slot accessor.
Second most efficient way is to use a CLOS slot accessor, or
slot-value with a constant slot name argument, but in
circumstances other than specified above. This may be up to 3 times as
slow as the method described above.
(defclass foo () ((bar))) ;; Fast: specializer and never assigned to (defmethod quux ((foo foo) new) (let ((old (slot-value foo 'bar))) (setf (slot-value foo 'bar) new) old)) ;; Slow: not a specializer (defmethod quux ((foo foo) new) (let* ((temp foo) (old (slot-value temp 'bar))) (setf (slot-value temp 'bar) new) old)) ;; Slow: assignment to FOO (defmethod quux ((foo foo) new) (let ((old (slot-value foo 'bar))) (setf (slot-value foo 'bar) new) (setf foo new) old))
Note that when profiling code such as this, the first few calls to the generic function are not representative, as the dispatch mechanism is lazily set up during those calls.