我有一个系统,该系统生成决策树并将其转换为嵌套的Common Lisp if
语句,并带有谓词,该谓词检查变量值是>=
还是<=
给定整数,例如>
(LAMBDA (V1 V2)
(IF (>= V1 2)
(IF (<= V1 3)
(IF (<= V2 3)
(IF (>= V2 2) 16 (IF (>= V2 1) 6 0))
(IF (<= V2 4) 10 0))
(IF (<= V1 4)
(IF (>= V2 1) (IF (<= V2 3) 6 0) 0)
0))
(IF (>= V1 1)
(IF (>= V2 2) (IF (<= V2 4) 10 0) 0)
0)))
然后,我使用eval
来编译Lisp代码,从而产生比解释原始决策树要快得多的函数。但是,此编译步骤花费了惊人的长时间:具有5000个嵌套ifs的函数要花一分钟多的时间才能编译(在powerbook上的Clozure Common Lisp中),即使生成if语句大约需要100毫秒。为什么这么简单的结构要花这么长时间?我可以做些什么来大大加快它的速度,也许可以声明一下?非常感谢您提供的任何提示。
答案 0 :(得分:6)
用于编译函数的实际可移植函数称为COMPILE
。
您可以告诉Common Lisp编译器通过降低optimize
,speed
,space
和debug
的{{1}}质量来减少工作量-是否具有任何影响都取决于实施。
Clozure CL编译器通常不是最聪明的编译器,但是相对较快。通常,我认为编译器维护人员可能会为您提供更多有关如何加快编译速度的提示。通常我会找三个
下一个选项是使用Lisp解释器。通常,它们的定义时间开销很小-但是代码通常在运行时运行慢得多。在某些问题域中,可以采用一种混合方法:编译不经常更改的代码并解释不经常更改的代码。
答案 1 :(得分:4)
您当然可以(declare (optimize (compilation-speed 3)))
,并且可能会降低其他品质(请参见http://clhs.lisp.se/Body/d_optimi.htm#optimize)。
但是,我猜编译缓慢是由编译器进行的优化引起的,因此执行时的结果似乎不太快。但也许不是,您必须进行试验。
我还会考虑使用域知识可以进行哪些优化。提示也可能来自分析您生成的函数上的disassemble
的输出。
最后,如果不同值的数量不太大,也许您可以将决策树转换为查找表。