4

我正在构建一些其他人编写的旧 Common Lisp 代码,其中包括一些函数开头的如下行:

(declare (ftype (function (&rest float) float) + - * min max))

我的理解是这样做的目的是告诉编译器表格末尾列出的五个函数只会传递浮点数。编译器可以使用此信息来创建更高效​​的代码。

一些 Lisps 不会抱怨这个声明(ABCL、CCL、ECL、LispWorks、CLISP),但是 SBCL 在默认配置中不会接受这个声明。SBCL 可以通过放置来接受它

(unlock-package 'common-lisp)

在 .sbclrc 初始化文件中。这就是我过去一年左右一直在做的事情。我认为这是必需的,因为 +、- 等位于该包中,并且代码会更改这些函数的声明。

我的问题是:声明 + 和 min 等内置函数的函数类型可以对 SBCL 中的编译代码产生有益的影响吗?(如果可以,那么为什么 SBCL 默认会抱怨这些声明?)我最好删除此类 ftype 声明,然后删除unlock-package.sbclrc 中的行吗?

谢谢。

4

1 回答 1

9

我的理解是这样做的目的是告诉编译器表格末尾列出的五个函数只会传递浮点数。编译器可以使用此信息来创建更高效​​的代码。

此外,它们只会返回浮点数。在某些优化设置下,Common Lisp 编译器不会生成运行时检查,并且可能只生成用于浮点计算的代码。此外,SBCL 可能会在某些情况下显示编译时警告,其中它检测到代码违反了类型声明。

它也是错误的来源,因为从现在开始(在声明的范围内)基本函数,如+-被声明为不适用于其他数字类型(整数、复数,...)。

那么,这些声明的目的是什么?由于它是可移植代码(并且大多数实现不实现编译时类型检查),它只能用于优化目的。其中一些在 SBCL 中可能不是必需的,因为它使用类型推断。

为什么 SBCL 默认不允许更改内置功能?这是为了防止你的脚开枪:你正在改变基本语言。现在基本的数值运算可能会导致错误。

处理方法:

  • 仅使用本地声明,不要全局更改语言。您指出这些仅在本地声明-很好。

  • 而是声明变量的值

  • 为浮点情况编写特殊函数并将它们声明为内联。

  • 仅在编译这几个函数时解锁包 CL。以后保持锁定。

我的问题是:声明 + 和 min 等内置函数的函数类型可以对 SBCL 中的编译代码产生有益的影响吗?

您可以通过查看反汇编代码和分析来检查。确保使用正确的优化设置编译函数。在 Common Lisp 中,该函数DISASSEMBLE应该以可读的方式向您显示机器代码。SBCL 编译器还应该告诉您它是否无法优化已编译的代码。

于 2013-01-01T10:48:21.687 回答