From: Gerard Flynn
Subject: Efficient array initialization
Date: 
Message-ID: <newscache$tqwb5h$iq1$1@news.tiscali.fr>
Hi,

  Is there an efficient way to initialize a large array of structures in 
lisp (cmucl) ?

  My structure definition looks like this:

    (defstruct point
      (val1 0 :type fixnum)
      (val2 0 :type fixnum))

  If  I do this :

   (make-array a1 (list 500 500)
                  :element-type point
                  :initial-element (make-point))

  the creation is fast but all of the elements are shared.

  If I do a loop and call (make-point) for each element, the initialization 
takes almost a minute.

  I've thought about using a macro with :initial-contents but that would 
still call (make-point) just as many times.

  Is there some other way ?

  Gerard Flynn

From: Ørnulf Staff
Subject: Re: Efficient array initialization
Date: 
Message-ID: <6uu1iqqppb.fsf@wirth.ping.uio.no>
[ Gerard Flynn ]

>   Is there an efficient way to initialize a large array of structures in 
> lisp (cmucl) ?
> 
>   My structure definition looks like this:
> 
>     (defstruct point
>       (val1 0 :type fixnum)
>       (val2 0 :type fixnum))
> 
>   If  I do this :
> 
>    (make-array a1 (list 500 500)
>                   :element-type point
>                   :initial-element (make-point))
> 
>   the creation is fast but all of the elements are shared.
> 
>   If I do a loop and call (make-point) for each element, the initialization 
> takes almost a minute.

You're probably running interpreted versions of make-point or your
initialization loop (or both).  On my system with cmucl,
making an array by iterating (* 500 500) times over
(setf (aref a i j) (make-point)) takes 0.7 seconds and conses
5 MB.  Interpreted, the exact same code takes 91 seconds and conses
104 MB.

-- 
�rnulf
From: Gabe Garza
Subject: Re: Efficient array initialization
Date: 
Message-ID: <87fzua6tgm.fsf@ix.netcom.com>
Gerard Flynn <············@libertysurf.fr> writes:

>   My structure definition looks like this:
> 
>     (defstruct point
>       (val1 0 :type fixnum)
>       (val2 0 :type fixnum))
> 
>   If  I do this :
> 
>    (make-array a1 (list 500 500)
>                   :element-type point
>                   :initial-element (make-point))
> 
>   the creation is fast but all of the elements are shared.
> 
>   If I do a loop and call (make-point) for each element, the initialization 
> takes almost a minute.

In addition to the other suggestion about making sure that the code
that initializes the array is compiled and not interpreted, you may
want to consider something like: 
  
   (make-array a1 (list 500 500 2) :element-type fixnum) 

If you access the array the functions with a point theme, like:

(defun set-point (point-array x y point)
  (setf (aref point-array x y 0) (point-val1 point))
  (setf (aref point-array x y 1) (point-val2 point)))

you can still have abstraction...

Gabe Garza