[Openmcl-devel] Cost of AREF?

Steven Nunez steve_nunez at yahoo.com
Fri Oct 25 21:40:16 PDT 2019

Does anyone know if AREF is an 'expensive' operation? I've got two versions of a function that differ, mostly, in what they loop over:

(defun ep1 (coefficients x)"SIMPLE-ARRAY version of coefficients."
  (declare (double-float x)((simple-array double-float) coefficients)
       (optimize(speed 3)(safety 0)))
  (let ((sum 0d0))
    (declare (double-float sum))
    (dotimes (index (length coefficients))
      (setf sum (+ (aref coefficients index)
                (* x sum))))
    (the double-float sum)))
(defun ep2 (coefficients x)"LIST version of coefficients."
  (declare (optimize(speed 3)(safety 0)))
  (assert (typep coefficients 'list) () "COEFFICIENTS must be a LIST")
     (let((sum (car coefficients)))
       (declare (double-float sum x))
       (loop for i double-float in (cdr coefficients)
      do (setf sum (+ i (* x sum))))
The list version executes faster than the simple-array version, which I find surprising. Not by a great deal, but consistently faster. As I understand the layout of the LIST version, the double-float is in the CAR of the CONS, saving a pointer dereference to get the value, but the loop still needs to dereference the CDR pointer. In the SIMPLE-ARRAY version, the DOUBLE-FLOATS are laid out in contiguous memory, which in theory should be faster to access. I think I've seen similar behaviour before, with loops over short lists out-performing arrays up to a certain length.
The only thing I can think of is that AREF might be a more expensive operation than reading the car, so for short lists the pointer dereferencing doesn't make a significant difference. Does that sound like a reasonable theory?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.clozure.com/pipermail/openmcl-devel/attachments/20191026/ac34f290/attachment.htm>

More information about the Openmcl-devel mailing list