From the discussion above, we can see that the standard descriptor representation has many problems, the worst being number consing. Common Lisp compilers try to avoid these descriptor efficiency problems by using non-descriptor representations. A compiler that uses non-descriptor representations can compile this function so that it does no number consing:
If a descriptor representation were used, each iteration of the loop might cons two floats and do three times as many memory references.(defun multby (vec n) (declare (type (simple-array single-float (*)) vec) (single-float n)) (dotimes (i (length vec)) (setf (aref vec i) (* n (aref vec i)))))
As its negative definition suggests, the range of possible non-descriptor representations is large. The performance improvement from non-descriptor representation depends upon both the number of types that have non-descriptor representations and the number of contexts in which the compiler is forced to use a descriptor representation.
Many Common Lisp compilers support non-descriptor representations for float types such as single-float and double-float (section 5.11.7.) Python adds support for full word integers (see section 5.11.6), characters (see section 5.11.11) and system-area pointers (unconstrained pointers, see section 6.5.) Many Common Lisp compilers support non-descriptor representations for variables (section 5.11.3) and array elements (section 5.11.8.) Python adds support for non-descriptor arguments and return values in local call (see section 5.11.10) and structure slots (see section 5.11.9).