我建立在其他人编写的一些旧的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声明,然后摆脱.sbclrc中的unlock-package
行?
谢谢。
我的理解是,这样做的目的是告诉编译器,表单末尾列出的五个函数将仅通过浮点数传递。编译器可以使用此信息来创建更有效的代码。
而且,它们只会返回浮点数。使用某些优化设置,Common Lisp编译器不会生成运行时检查,而只能生成用于浮点计算的代码。在某些情况下,SBCL可能会在检测到代码违反类型声明的情况下显示编译时警告。
它也是错误的来源,因为从现在开始(在声明的范围内),诸如+
和-
之类的基本函数被声明为不适用于其他数字类型(整数,复数,...)。
所以,这些声明的目的是什么?由于它是可移植的代码(并且大多数实现未实现编译时类型检查),因此只能用于优化目的。在SBCL中,其中某些可能不是必需的,因为它使用类型推断。
为什么SBCL默认不允许更改内置功能?这样做是为了防止脚上的射击:您正在更改基本语言。现在,基本的数字运算可能会导致错误。
处理方式:
仅使用本地声明,请勿全局更改语言。您指示这些仅在本地声明-很好。
改为声明变量的值
为float情况编写特殊功能,并内联声明它们。
仅在编译这几个函数期间解锁软件包CL。以后再将其锁定。
我的问题是:声明内置函数(例如+和min)的函数类型可以对SBCL中的编译代码产生有益的影响吗?
您可以通过查看反汇编的代码以及配置文件来进行检查。确保使用正确的优化设置编译功能。在Common Lisp中,功能DISASSEMBLE
应该以可读的方式向您显示机器代码。 SBCL编译器还应告诉您是否无法优化编译后的代码。