>>>>> "Michael" == Michael A Koerber <[EMAIL PROTECTED]> writes:

    Michael> Ray,

Sorry for the delay....

I couldn't really test this because some functions are missing.

    Michael> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    Michael> ;;;                        SUB-ARRAY VERSION USES AREF

[snip]

    Michael>      (let* (
    Michael>     (new-array (make-array array-dims
    Michael>                            :element-type (array-element-type array)))
    Michael>     ;; and create a displaced array
    Michael>     (new-array-displaced (make-array (array-total-size new-array)
    Michael>                                      :element-type (array-element-type 
array)
    Michael>                                      :displaced-to new-array)))
    Michael>        ;; now populate and return the new-array
    Michael>        (dotimes (n (array-total-size new-array) new-array)
    Michael>    (setf (aref new-array-displaced n)
    Michael>          (apply #'aref array (nth n array-indexes)))))))

I suspect this is slow for several reasons:

o nth is slow
o apply might be slow.
o Generic aref is called because the compiler doesn't know the type of
  ARRAY
o Array bounds checking on 3 indices is done, as well as computing the
  actual offset from the 3 indices.

    Michael> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    Michael> ;;;              THIS VERSION USES ELT AND DISPLACED ARRAYS
    Michael> (defun sub-array (array &rest index-specs)
    Michael>      (let* ((da (sequence-displaced-to array))
    Michael>       (new-vector (make-array (length row-major-indexes)
    Michael>                               :element-type (array-element-type array)
    Michael>                               :initial-contents
    Michael>                               ;; extract the decimated data
    Michael>                               (let ((new))
    Michael>                                 (dolist (rmi row-major-indexes (nreverse 
new))
    Michael>                                   (push (elt da rmi) new)))))
    Michael>       (new-array (make-array array-dims
    Michael>                            :element-type (array-element-type array)
    Michael>                            :displaced-to new-vector)))

    Michael>        new-array)))


I'm guessing this is fast because most of the issues above don't
occur.  Yes, elt is usually slow, but bounds checking and offset
computation is gone.

If you had a simpler example, it would be easier to figure out.

I note that in f2cl, displaced 1D arrays are heavily used when
necessary to pass array slices to "Fortran" routines.  This would be a
major hit on performance if the displaced arrays were used as is.
However, what happens is that all displaced arrays are ultimately
displaced to a specialized array.  So all of the displacements and
tracked down and the offset is kept track of.  Then within the body of
the routine, whenever we would have used (aref original-arg-array n),
we use (aref actual-underlying-array (+ n computed-offset)).  This
gets us to within about 1.5 to 2 times that of Fortran.  Without, it's
more like 5-10 times.

Ray


Reply via email to