4

我真正想要的是源内测试定义:

假设我有一个 asdf 系统:

(defsystem simple-system
  :serial t
  :components ((:module "src"
                        :components
                        ((:file "0-package")
                         (:file "1-tests-stubs")
                         (:file "2-code") ...))))

还有另一个系统来测试第一个:

(defsystem simple-system-tests
  :serial t
  :components ((:module "src"
                        :components
                        ((:file "0-package")
                         (:file "1-tests-real")
                         (:file "2-code") ...))))

它们之间的唯一区别是在simple-systemI have 1-tests-stubswhere 在simple-system-testsI have 中1-tests-real。在1-tests-stubs我定义了一个宏(defmacro def-test (&rest _args) nil),它在1-tests-real.

现在我想编译simple-systemwith(declare (optimize (safety 0) (debug 0) (speed 3)))simple-system-testswith 相反(declare (optimize (safety 3) (debug 3) (speed 0)))

我该怎么做(在哪里放置以及如何以通用方式为这两个系统设置这些声明)?

如何重用simple-systemin 的定义simple-system-tests(不要重复自己重新键入所有模块/组件)?

而且我必须确保所有文件都针对每个系统使用不同的优化级别重新编译。

此外,如果每个系统文件仅在它们被更改时才重新编译(每个系统的已编译文件的自己的副本?),那将是很好的。

4

3 回答 3

4

安全性低的优化。

一般来说,我建议像这样以零安全性编译整个系统(库或应用程序):

(declare (optimize (safety 0) (debug 0) (speed 3)))

将零安全性与类型声明结合使用可能会改变程序的语义,并且错误可能会使程序崩溃。它甚至可能会打开安全漏洞。

我对生产代码的建议是这样的:

  • 使用 = 3 优化速度关键部件speed并保留通常的安全设置(2 或 3)。

  • 如果需要较低的安全设置以进一步提高速度,请仅在需要时声明。Common Lisp 提供了函数局部声明以及一种特殊的局部运算符,可以进一步限制声明适用的代码区域。

使优化设置可变

* (defparameter *safety* 0)

这不起作用,因为安全值需要是数字:

*SAFETY*
* (defun foo (a) (declare (optimize (safety *safety*))) (1+ a))
; in: DEFUN FOO
;     (OPTIMIZE (SAFETY *SAFETY*))
; 
; caught WARNING:
;   Ignoring bad optimization value *SAFETY* in: (OPTIMIZE (SAFETY *SAFETY*))
; 
; compilation unit finished
;   caught 1 WARNING condition

FOO

但这有效,使用读取时评估:

* (defun foo (a) (declare (optimize (safety #.*safety*))) (1+ a))
WARNING: redefining COMMON-LISP-USER::FOO in DEFUN

FOO

还可以插入整个声明:

* (defparameter *optimization-declaration* '(declare (optimize (safety 0))))

*OPTIMIZATION-DECLARATION*
* (defun foo (a) #.*optimization-declaration* (1+ a))
WARNING: redefining COMMON-LISP-USER::FOO in DEFUN

FOO
* 
于 2017-08-18T12:02:01.023 回答
3

 优化级别

您可以尝试使用:around-compile

(defsystem simple-system
  :serial t
  :around-compile (lambda (next)
                    (proclaim '(optimize (debug 3) 
                                         (safety 3)
                                         (debug 3)
                                         (speed 0)))
                    (funcall next))
  :components ((:module "src"
                        :components
                        (...))))

文档说(强调我的):

使用此钩子,您可以实现以下效果:本地重命名包、绑定 *readtables* 和其他语法控制变量、处理警告和其他条件、声明一致的优化设置、保存代码覆盖率信息、维护有关编译时间的元数据,设置 gensym 计数器和 PRNG 种子以及其他非确定性来源,覆盖源位置和/或时间戳系统,检查某些编译时副作用是否适当平衡等。

围绕系统中正在编译的每个文件执行该操作;您可以隐藏:around-compile模块中所有文件或特定文件的值。

于 2017-08-18T09:48:31.387 回答
0

我希望这只是一个错字,在这些示例中,同一个文件 0-package 由两个系统共享。如果不是,你会输得很惨,这都是你的错。

于 2017-08-22T02:04:05.647 回答