在以下程序中,删除该行
(declare (type (simple-array bit) arr))
使用 SBCL 使运行时间增加了 3 倍以上。
defclass
中给出的类型信息宏通过 :type
另一方面似乎对性能没有影响。(defclass class-1 () ((arr :type (simple-array bit))))
(defun sample (inst)
(declare (type class-1 inst))
(let ((arr (slot-value inst 'arr)))
(declare (type (simple-array bit) arr)) ;; 3x running time without
(map-into arr #'(lambda (dummy) (if (< (random 1.0) 0.5) 0 1)) arr)))
(let ((inst (make-instance 'class-1)))
(setf (slot-value inst 'arr) (make-array 10000 :element-type 'bit))
(loop for i from 1 to 10000 do (sample inst)))
如何在无需声明
arr
的情况下获得相同的性能优势?插槽 a simple-array bit
每次我使用它?后者特别烦人,因为(据我所知)需要通过 let
引入绑定(bind)。或每次都类似;我不能只写(slot-value inst 'arr)
在我需要的地方。
最佳答案
第一总之,这是一个特定于 SBCL 的问题,您可能会在 SBCL 用户列表上得到更好的答案。不同的编译器做不同的优化,并且大多数忽略至少一些声明。
第二 ,你应该让绑定(bind)arr
因为你用了两次。
第三 , 你可以使用 the
如果你想避免让绑定(bind):
(the (simple-array bit) (slot-value inst 'arr))
第四 ,如果您希望编译器推断类型,请使用特定的阅读器而不是
slot-value
:(defclass c () ((arr :type (simple-array bit) :reader c-arr)))
(defun sample (inst)
(declare (type class-1 inst))
(let ((arr (c-arr inst)))
(map-into arr #'(lambda (dummy) (random 2)) arr)))
c-arr
应该允许编译器更容易地推断值类型,但是(正如您自己发现的那样!)您可能需要声明其返回类型:(declaim (ftype (function (c) (simple-array bit)) c-arr))
显然,原因是 SBCL 忽略了槽类型声明。
关于performance - 用于性能的 defclass 类型信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23060868/