Defstobj-element-type
Specify the element type for a stobj array field
This topic assumes familiarity with the defstobj event. It
documents the :element-type keyword for a stobj array field. Note that
:element-type is only supported for stobj array fields, not other sorts
of stobj fields.
Consider a stobj array field with :type of the form (array
etype (n)), for example, (array bit (8)). Logically, this
“array” is a list, each of whose elements has the indicated type,
etype — in our example, the type, bit (i.e., 0 or 1). In raw
Lisp, however, an array is allocated. The Lisp code that allocates that array
can specify the type of its elements, and may specify that element type to be
bit. But it would also be legal to specify a weaker type. In particular,
the type t is a legal type for every object, and this can be specified by
including :element-type t in your stobj array field.
Perhaps surprisingly, Lisp code may run faster when the element type in a
raw Lisp array is t rather than a more restrictive type. The
:element-type of a stobj array field may be specified to be t to
give this behavior, by using :element-type t. You can do your own
experiments to decide whether that is helpful, in particular by considering
community-book books/demos/element-type.lisp. That file starts
with the following events and then times reading and writing the stobj
array.
(defconst *ar-size* (expt 10 8))
(defstobj st1
(ar1 :type (array double-float (*ar-size*))
:element-type t ; Omit this line to compare times with or without it.
:initially 0)
; Optional:
:inline t)
Our own experiments with this file have produced the following results (for
both realtime and runtime) with CCL and SBCL on a 2019-era MacBook Pro (2.4
GHz 8-Core Intel Core i9). They suggest the use of :element-type t with
read-intensive applications when using CCL. Results may be very different
without the use of :inline t, and of course these results may not be
indicative of your own experience with various applications, Lisps, and
operating systems.
(time$ (reads-st1 st1 *ar-size*))
Results:
CCL
With :element-type t
0.27 seconds (32 bytes allocated)
Without :element-type t
; 0.47 seconds (32 bytes allocated)
SBCL
With :element-type t
0.23 seconds (0 bytes allocated)
Without :element-type t
0.21 seconds (0 bytes allocated)
(time$ (writes-st1 st1 (to-df 2) *ar-size*))
Results:
CCL
With :element-type t
1.17 seconds (128 bytes allocated);
Without :element-type t
0.27 seconds (128 bytes allocated)
SBCL
With :element-type t
0.24 seconds realtime (0 bytes allocated)
Without :element-type t
0.25 seconds (0 bytes allocated).
Currently the legal values for :element-type are t and the
default value, which is the element type specified in the :type field of
the stobj array field specification. This could change if experiments suggest
something different.