[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))))
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