David J Cooper Jr <[EMAIL PROTECTED]> writes:
> Does the following make any sense or ring any bells with anyone?:
The problem is that alien:slot is very inefficient if the type of the
argument is not known. In interpreted version of alien:slot is used
in this case and the interpreted version creates and IR1-converts a
function for each access.
Declaring types helps a lot in this case:
(defun extract-cpoint (cpoint)
(declare (type (alien:alien (* cpoint)) cpoint))
(list (alien:slot cpoint 'x)
(alien:slot cpoint 'y)
(alien:slot cpoint 'z)))
Also note that it is not possible to pass a simple pointer between
Lisp functions, the pointer must be boxed. The remaining consing is
probably caused by boxing the alien pointer and allocating the
doubles. It's sometimes possible to pass a fixnum (when you know that
the pointer is word aligned) or a pair of fixnums instead of boxed
pointer:
(defun test (&key (times 1000) (inline? nil))
(let ((init (ext:get-bytes-consed)))
(let ((foop (alien:make-alien cpoint)))
(setf (alien:slot foop 'x) 0.0d0
(alien:slot foop 'y) 1.0d0
(alien:slot foop 'z) 2.0d0)
(dotimes (n times)
(if inline?
(list (alien:slot foop 'x)
(alien:slot foop 'y)
(alien:slot foop 'z))
(extract-cpoint (sys:sap-int (alien:alien-sap foop)))))
(alien:free-alien foop))
(- (ext:get-bytes-consed) init)))
(defun extract-cpoint (cpoint)
(alien:with-alien ((cpoint (* cpoint) :local (sys:int-sap cpoint)))
(list (alien:slot cpoint 'x)
(alien:slot cpoint 'y)
(alien:slot cpoint 'z))))
The lists take (* 1000 3 (+ (+ 4 8) 8)) = 60000 bytes. Consing is now
down to 72024 bytes; don't know where the rest is used.
Helmut.