在lisp中访问数组的优化

And*_* S. 1 lisp optimization sbcl common-lisp

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

(defun getref (seq k)
  (declare (optimize (speed 3) (safety 0)))
  (declare (type (vector fixnum *) seq) (type fixnum k))
  (aref seq k))
Run Code Online (Sandbox Code Playgroud)

编译,它说:

; 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
Run Code Online (Sandbox Code Playgroud)

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

cor*_*ump 5

您得到的优化提示来自于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"
  ...)
Run Code Online (Sandbox Code Playgroud)

它有一条评论说:

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.
Run Code Online (Sandbox Code Playgroud)

数组的代码非常复杂,很难说为什么以及如何设计事物。您可能应该询问 SBCL 开发人员sbcl-help。请参阅Sourceforge 上的邮件列表部分。

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


Rai*_*wig 5

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

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