On Fri, Feb 14, 2003 at 07:15:04PM -0500, rif wrote:

> In order to get good performance, will I have to make a single
> function that takes the whole vector and does all the operations
> internally (i.e., a function called square-vector for instance), or
> can I build a higher-order function which takes a procedure like
> square and operates on the elements of the vector?  It seems that if
> I'm guaranteed to lose as soon as I call a function with a
> double-float argument, that it's going to be hard to do this fast.
> What're good strategies here?

Perhaps judicious use of inlined functions and macros (possibly
compiler macros, if you still want to have function-like behaviour
under some circumstances...)? E.g.:

(declaim (inline square-df))
(defun square-df (x)
  (declare (optimize (speed 3) (safety 0) (debug 0))
           (double-float x))
  (* x x))

(deftype df->df-func () `(function (double-float) double-float))

(deftype df-vector () `(simple-array double-float 1))

(defmacro %nmap-df-vector (func df-vector)
  (let (($func (gensym "FUNC"))  
        ($df-vector (gensym "DF-VECTOR"))
        ($index (gensym "INDEX")))
    `(let ((,$func ,func)
           (,$df-vector ,df-vector))
       (declare (type df-vector ,$df-vector)
                (type df->df-func ,$func))
       (loop for ,$index of-type fixnum from 0 below (length ,$df-vector)
         do (setf (aref ,$df-vector ,$index)
                  (funcall ,$func (aref ,$df-vector ,$index)))))))
 
(define-compiler-macro nmap-df-vector (func df-vector)
  `(%nmap-df-vector ,func ,df-vector))

(defun nmap-df-vector (func df-vector)
  (%nmap-df-vector func df-vector))

(defvar *vector* (make-array (list 4096) :element-type 'double-float))

;; Runs in 0.32 seconds, 0 bytes consed
(defun test-1 ()
  (declare (optimize (speed 3) (safety 0) (debug 0)))
  (dotimes (i 30000)
    (nmap-df-vector #'square-df *vector*)))

;; Runs in 64.33 seconds with 3.64 gigabytes consed
(defun test-2 ()
  (declare (optimize (speed 3) (safety 0) (debug 0)))
  (dotimes (i 30000)
    (funcall #'nmap-df-vector #'square-df *vector*)))


Reply via email to