在Lisp中访问数组的优化

时间:2018-10-29 11:36:22

标签: optimization lisp common-lisp sbcl

我正在尝试学习如何在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的函数中(而且我也这样做,因为我需要可调整的向量),所以也会发生这种情况。我该如何解决?

2 个答案:

答案 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。

目前似乎更希望尽可能使用简单数组。