我正在尝试学习如何在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的函数中(而且我也这样做,因为我需要可调整的向量),所以也会发生这种情况。我该如何解决?
答案 0 :(得分:5)
这不是一个问题,也不是一个错误。只是来自SBCL编译器的信息(注释),它不能更好地优化代码。该代码将正常工作。您可以放心地忽略它。
如果您不能使用简单的矢量(一维简单数组),那么这就是要为此付出的代价:aref
可能会稍微慢一些。
答案 1 :(得分:4)
您获得的优化提示来自deftransform
中定义的sbcl/src/compiler/generic/vm-tran.lisp
的文档字符串:
(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部分
Sourceforge。
目前似乎更希望尽可能使用简单数组。