This section describes ways to perform certain operations as efficiently as possible, including vector access and raw 32-bit arithmetic. Additionally in 64-bit LispWorks, raw 64-bit arithmetic is possible.

You can make vectors of certain element types which allow the most efficient access possible when compiled with suitable optimize qualities.

To do this:

- Make a vector with make-typed-aref-vector.
- Access the vector using typed-aref and
`(setf typed-aref)`

with a`type`argument of double-float, float, single-float, int32,`(unsigned-byte`

or`n`)`(signed-byte`

where`n`)`n`= 8, 16 or 32.Additionally, in 64-bit LispWorks the types

`(unsigned-byte 64)`

and`(signed-byte 64)`

are supported. - Compile the access with
`safety 0`

(and for float types,`float 0`

) and a constant`type`.

See typed-aref for more details and examples.

Efficient access to foreign arrays is also available. See fli:foreign-typed-aref in the *Foreign Language Interface User Guide and Reference Manual*.

The INT32 API provides a way to perform optimal raw 32-bit arithmetic. Note that, unlike Lisp integer types, this is modulo 2^32 like the C `int`

type.

The INT32 symbols are all in the `system`

package.

The Lisp type int32 reads 32 bits of memory, like `(signed-byte 32)`

, but the data is in int32 format for use with the INT32 API.

When optimized correctly, the intermediate int32 objects are not constructed.

In unoptimized code, sequences of operations like:

(sys:int32+ (sys:int32- a b) (sys:int32- c d))

will generate intermediate int32 objects for the results of the subtraction, but the compiler can optimize these away because it knows that the function int32+ consumes int32 objects.

**Note:** the INT32 API is not designed to optimize sys:int32 objects passed as arguments.

The INT32 API contains the type int32, a vector type simple-int32-vector and accessor, functions to convert int32 to and from integer, some constant int32 values, and a full range of operators for mod 2^32 arithmetic.

You can find all these by evaluating:

(apropos "INT32" "SYSTEM" t)

For details for each, see the entries starting with int32 in 47 The SYSTEM Package.

The optimization works safely but without boxing when possible. You need:

(optimize (float 0))

to get the optimization. This float level affects whether INT32 operations are optimized. This declaration must be placed at the start of a function (not on an inner let or locally form).

In this example the safety level assures a second optimization in fli:foreign-typed-aref:

(defun incf-signed-byte-32 (ptr index) (declare (optimize (safety 0) (float 0)) (type fixnum index)) (setf (fli:foreign-typed-aref 'sys:int32 ptr index) (sys:int32-1+ (fli:foreign-typed-aref 'sys:int32 ptr index))) ;; return ptr, since otherwise the int32 would ;; need to be boxed to return it ptr)

The INT64 API provides a way to perform optimal raw 64-bit arithmetic. Note that, unlike Lisp integer types, this is modulo 2^64 like the C `long`

`long`

or int64 types.

The INT64 symbols are all in the `system`

package.

The Lisp type int64 reads 64 bits of memory, like `(signed-byte 64)`

, but the data is in int64 format for use with the INT64 API.

When optimized correctly, the intermediate int64 objects are not constructed.

In unoptimized code, sequences of operations like:

(sys:int64+ (sys:int64- a b) (sys:int64- c d))

will generate intermediate int64 objects for the results of the subtraction, but the compiler can optimize these away because it knows that the function int64+ consumes int64 objects.

**Note:** the INT64 API is not designed to optimize sys:int64 objects passed as arguments.

The INT64 API contains the type int64, a vector type simple-int64-vector and accessor, functions to convert int64 to and from integer, some constant int64 values, and a full range of operators for mod 2^64 arithmetic.

You can find all these by evaluating:

(apropos "INT64" "SYSTEM" t)

For details for each, see the entries starting with int64 in 47 The SYSTEM Package.

INT64 optimization occurs only in 64-bit LispWorks. The INT64 API is not optimized in 32-bit LispWorks.

The optimization works safely but without boxing when possible. You need:

(optimize (float 0))

to get the optimization. This float level affects whether INT64 operations are optimized. This declaration must be placed at the start of a function (not on an inner let or locally form).

In this example the safety level assures a second optimization in fli:foreign-typed-aref:

(defun incf-signed-byte-64 (ptr index) (declare (optimize (safety 0) (float 0)) (type fixnum index)) (setf (fli:foreign-typed-aref 'sys:int64 ptr index) (sys:int64-1+ (fli:foreign-typed-aref 'sys:int64 ptr index))) ;; return ptr, since otherwise the int64 would ;; need to be boxed to return it ptr)

octet-ref and base-char-ref (and their setters) are provided to allow efficient access to simple vectors of element type `(unsigned-byte 8)`

or base-char (that is, simple-base-strings) in the same code.

Other vector types are accepted, but for these specific string and binary vector types octet-ref and base-char-ref match what aref and `(setf aref)`

do except that they always take and return the same value/result type, and they are also more efficient than aref.

Use octet-ref and base-char-ref according to whether you work with elements of type integer or base-char.

*LispWorks® User Guide and Reference Manual - 01 Dec 2021 19:30:25*