在 lisp 中访问数组的优化

Optimization for accessing array in lisp

我正在尝试学习如何在 lisp 中进行类型声明。我发现 aref 会导致问题:

(defun getref (seq k)
  (declare (optimize (speed 3) (safety 0)))
  (declare (type (vector fixnum *) seq) (type fixnum k))
  (aref seq k))

已编译,它说:

; in: DEFUN GETREF
;     (AREF MORE-LISP::SEQ MORE-LISP::K)
; ==>
;   (SB-KERNEL:HAIRY-DATA-VECTOR-REF ARRAY SB-INT:INDEX)
; 
; note: unable to
;   avoid runtime dispatch on array element type
; due to type uncertainty:
;   The first argument is a (VECTOR FIXNUM), not a SIMPLE-ARRAY.
; 
; compilation unit finished
;   printed 1 note

所以在我想使用 aref 的所有其他函数中(我确实这样做了,因为我需要可调整的向量),这也会发生。我该如何解决?

您获得的优化提示来自 sbcl/src/compiler/generic/vm-tran.lisp 中定义的 deftransform 的文档字符串:

(deftransform hairy-data-vector-ref ((array index) (simple-array t) *)
  "avoid runtime dispatch on array element type"
  ...)

它有一条评论说:

This and the corresponding -SET transform work equally well on non-simple
arrays, but after benchmarking (on x86), Nikodemus didn't find any cases
where it actually helped with non-simple arrays -- to the contrary, it
only made for bigger and up to 100% slower code.

数组的代码非常复杂,很难说为什么以及如何设计这些东西。您可能应该在 sbcl-help 上询问 SBCL 开发人员。请参阅 the mailing lists 部分 源码。

目前,如果可能的话,似乎更倾向于使用简单数组。

这不是问题,也不是错误。它只是来自 SBCL 编译器的一条信息(注释),它无法更好地优化代码。该代码将正常工作。您可以放心地忽略它。

如果您不能使用简单向量(一维简单数组),那么这就是为此付出的代价:aref 可能会稍微慢一些。