In article <1272223060.5332.7.camel@...>,
Fredrik Tolf <fredrik@...> wrote:
> How would I do to create a very large array of some structure in SBCL to
> be as memory-conservative as possible?
> Consider the following code:
> (defstruct test a b)
> (type-of (make-array '(10 10) :element-type 'test))
> SBCL tells me that the type of the array is a (simple-array t (10 10)),
> and I guess that means that it's effectively holding pointers to
> structs. If I'm not mistaken, such a struct takes at least 16 bytes on a
> 64-bit machine (I don't know what other overhead SBCL imposes), and the
> array would require at least 8 bytes per element, which makes for at
> least 24 bytes per element, meaning at least 50% overhead. The overhead
> becomes even more obvious if the elements of the structure are, say,
> (unsigned-byte 8), where only two bytes should be required per element.
The space usage for structures goes like:
1. Header word (1 word)
2. Type descriptor (1 word)
... data ...
So the space overhead is 2 words/struct for the metadata and 1 more for
the pointer from the array.
> Would it be possible, somehow, to make SBCL store structures directly in
> the array, as I can make a C compiler do (with a "struct test
> array"), or will I have to live with this overhead unless I declare
> multiple arrays (one per structure element) and do away with structures
The problem is that this breaks object identity. The semantics of CL
dictate that, given A an array of TEST, I can do
(setf (aref A 0) (aref A 1))
and both indices should point to the same (wrt object identity) object.
For instance, side-effects to the structure in either index will be
reflected in the other.
It would be possible to hack up a special type of vectors or arrays that
doesn't preserve object identity. However, practically, it's probably
easier to use SB-ALIEN and work with a C array of structures if you
don't need pointers from the structures back to lisp objects. More
portably, you may be able to encode each structure in a fixnum or