Performance 为性能定义类类型信息
在以下程序中,删除该行Performance 为性能定义类类型信息,performance,common-lisp,sbcl,typing,clos,Performance,Common Lisp,Sbcl,Typing,Clos,在以下程序中,删除该行 (declare (type (simple-array bit) arr)) 使用SBCL使运行时间增加3倍以上。另一方面,通过:type在defclass宏中给出的类型信息似乎对性能没有影响 (defclass class-1 () ((arr :type (simple-array bit)))) (defun sample (inst) (declare (type class-1 inst)) (let ((arr (slot-value i
(declare (type (simple-array bit) arr))
使用SBCL使运行时间增加3倍以上。另一方面,通过:type
在defclass
宏中给出的类型信息似乎对性能没有影响
(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)))
(defclass class-1()((arr:type(简单数组位)))
(除样品(仪器)
(申报(1类仪表)
(let((arr(槽值指令arr)))
(声明(类型(简单数组位)arr));;3倍的运行时间
(映射到arr#’(lambda(虚拟)(if(<(随机1.0)0.5)0 1))arr)
(让((inst(使实例'class-1'))
(setf(插槽值inst'arr)(使数组为10000:元素类型'bit))
(从1到10000 do的i循环(样本仪器)))
如何在每次使用时都不必声明
arr
插槽a简单数组位
的情况下获得相同的性能优势?后者尤其令人讨厌,因为(据我所知)每次都需要通过let
或类似方式引入绑定;我不能只在需要的地方写(slot value inst'arr)
。首先,这是一个SBCL特定的问题,您可能会在SBCL用户列表中得到更好的答案。不同的编译器执行不同的优化,大多数编译器至少会忽略一些声明
第二次,您应该让bindarr
,因为您要使用它两次
第三个,如果要避免让绑定,可以使用:
(the (simple-array bit) (slot-value inst 'arr))
第四个,如果希望编译器推断类型,请使用特定读取器,而不是插槽值
:
(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忽略了插槽类型声明。添加类型信息会产生不同的效果,具体取决于您使用的编译器和有效的优化级别 对于优化编译器,它可能如下所示:
- 无信息:通用操作,速度相当快
- 类型声明可用:添加了在运行时检查此特定类型的操作->较慢
- 类型声明可用,高优化和低安全性:运行时没有添加类型检查操作,为该类型生成专门的代码->可能更快
摘要:由于添加了类型检查,类型声明可能会增加具有高安全性的运行时开销。专门的数据类型不一定更快,安全性低,优化程度高。使用读卡器是一个好主意,但它不能直接用于我。然而,使用您的类和函数名,读卡器加上以下各项才有效:
(declaim(ftype(function((c))(简单数组位))c-arr))
。有了它,甚至可以省略:type
,以及(declare(type class-1 inst))
。它可能应该是(declaim(ftype(function(c)(简单数组位))c-arr))
。两者似乎都起作用,我不知道为什么。我以前没用过那个表格。