performance - 用于性能的 defclass 类型信息

标签 performance common-lisp sbcl typing clos

在以下程序中,删除该行

    (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/

相关文章:

python - Numpy item 比 operator[] 更快

lisp - 你能在 LISP 中使用 'list' 命令获得点表示吗?

rss - 我应该使用哪个库来在 Common Lisp 中生成 RSS?

utf-8 - 如何让 quicklisp 在 Slime 中加载 rfc2388?

debugging - 在 Emacs 和 SLIME 中调试 Common Lisp 的有效方法是什么?

python - 为什么 Django 使用元组的元组来存储静态字典,我应该这样做吗?

python - 加速 scipy.integrate.quad()?

c - 前后增量运算符分析结果

import - 普通口齿不清 : How to import symbols of other packages inside a lexical scope only?

common-lisp - 如何将 buildapp 与预定义的 asd 文件一起使用