Lisp:测量函数的性能

时间:2012-07-21 11:43:44

标签: performance lisp common-lisp sbcl factorial

到目前为止,在测试编写相同函数的不同方法的速度时,我一直在使用time函数,通常它给了我很好的指示不同函数的相对速度(因为它们通常相差大约100k周期)。

但是,在尝试找到factorial函数的最快方法时,time一直缺乏。这些方法不仅仅相差10k-30k周期,而且它们的总时间也相差大约一半(我猜这是预期的)。

三个factorial函数:

(defun factorial-recusion (n)   ; 1st      
  (if (equal n 1) 
      1
      (* n (factorial (- n 1)))))

(defun factorial-loop (n)   ; 2nd
  (let ((solution 1))
    (loop for x from n downto 2
       do (setf solution (* solution x))
       finally (return solution))))

(defun factorial-do (n)     ; 3rd
  (let ((solution 1))
    (do ((x n (1- x)))
    ((< x 2) (return solution))
      (setf solution (* solution x)))))

所以,我想我有两个问题:

1。)factorial哪种方法应该最快(如果有的话),为什么?

2。)如果我通过一般方法找到更快的功能,那么最好的方法是什么(出于某种原因,我认为LOC是一个速度不好的指标)?也许有办法查看Lisp字节码的反汇编?或者可能有更好,更严格的方式?

我目前正在Ubuntu 12.04 x86-64上运行Linux 3.2.0-26,SBCL。

1 个答案:

答案 0 :(得分:5)

SBCL无法编译为'bytecode'。它编译为本机机器代码。

您可以使用DISASSEMBLE来反汇编Lisp函数。

一旦数字进入bignum范围,你的阶乘函数的速度主要由bignum算术乘法控制。

为了更清楚:你使用哪个迭代构造,DO或LOOP,并不重要。大部分时间花在倍增的bignums上。递归版本也没有多大区别。

这是一个典型的基准问题:许多简单的数字基准测试主要由几个算术运算的运行时间(如bignums的乘法)决定。它们不会测量一般语言操作速度的不同(例如各种类型的控制流程)。

具有快速bignum库的慢速Lisp可能比使用Lisp编写的Bignum代码的优化Lisp编译器更快。

相关问题