【问题标题】:SBCL optimization: function type declarationSBCL 优化:函数类型声明
【发布时间】:2017-09-19 10:00:53
【问题描述】:

如果我有一个接受函数参数的函数,出于优化目的,我可以将其声明为function,比如说

(defun foo (f)
   (declare (type function f))
   ...)

但是,我可以更具体:

(defun foo (f)
   (declare (type (function (double-float) double-float) f))
   ...)

即告诉f 将接受一个double-float 参数并返回一个double-float 值。然而,SBCL 似乎能够对前者进行更好的优化,而对于后者,它表示它不知道f 是否为fdefinition(尝试使用(optimize (speed 3)) 声明进行编译以重现)。

所以,我的问题是:

  • 我做错了吗?特别是如果 SBCL 对 function(function ...) 做完全相同的事情,我会接受它,但它实际上做得更糟。还是应该将其视为 SBCL 中的错误?

  • 由于某种原因,函数类型声明在 CL 中通常在优化方面没有用吗?

系统信息:SBCL 1.3.18

【问题讨论】:

  • 我似乎无法在 SBCL 1.3.21 / Linux 上重现这一点。 (defun foo (f) (declare (type (function (fixnum) fixnum) f)) (funcall f 10)) 不给出警告,反汇编与(type function f) 相同。 SBCL 还检查提供给(funcall f ...) 的参数是否是一个fixnum,并得出FOO 返回一个fixnum。
  • @jkiiski Windows 目前只有 1.3.18 版本,将使用 1.3.21 进行编译和检查

标签: optimization lisp common-lisp sbcl


【解决方案1】:

来自 SBCL 手册(4.2.3 运行现有程序):

一些不正确的声明只能被运行时类型检测到 检查 [...] 因为 SBCL 编译器做的更多 类型推断比其他 Common Lisp 编译器,所以不正确 声明会造成更大的损害

有可能,这就是为什么你的函数在包含变量类型声明的情况下会变得更糟。

进一步:

最常见的问题是初始值不变的变量 与类型声明不匹配。不正确的常数初始值 将始终被编译时类型错误标记,它们是 一旦找到就很容易修复。考虑这个代码片段:

 (prog (foo)
   (declare (fixnum foo))
   (setq foo ...)
   ...) 

这里 foo 的初始值是 nil,但被声明为一个 fixnum。即使它从未被读取,a 的初始值 变量必须与声明的类型匹配。有两种方法可以解决此问题 问题。更改声明

 (prog (foo)
   (declare (type (or fixnum null) foo))
   (setq foo ...)
   ...) 

或者改变初始值

 (prog ((foo 0))
   (declare (fixnum foo))
   (setq foo ...)
   ...)

这是来自当前版本 SBCL (1.4) 的手册,因此它可能适用于您的情况,也可能不适用于您的情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多