【问题标题】:Lisp: Measuring performance of functionsLisp:测量函数的性能
【发布时间】:2012-07-21 11:43:43
【问题描述】:

到目前为止,在测试编写相同函数的不同方法的速度时,我一直在使用 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。

【问题讨论】:

  • 你使用的是什么 CL 实现?

标签: performance lisp common-lisp sbcl factorial


【解决方案1】:

SBCL 不会编译为“字节码”。它编译为本机机器码。

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

一旦数字进入 bignum 范围,阶乘函数的速度将由 bignum 算术乘法决定。

为了更清楚:您使用哪种迭代构造(DO 或 LOOP)并不重要。大部分时间都花在乘法上。递归版本也没有太大区别。

这是一个典型的基准测试问题:许多简单的数值基准测试都由一些算术运算的运行时间(例如 bignums 的乘法)支配。它们不会测量通用语言操作(如各种类型的控制流)的速度差异。

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

【讨论】:

  • 哦,糟糕,我把它放在那里了。起初我写了(和(...)(返回解决方案),但后来我意识到那是多么愚蠢。拆卸似乎是我需要的。所以我认为这也是衡量性能的最佳方法?你认为有一个直回答我的第一个问题?谢谢!
猜你喜欢
  • 2013-03-23
  • 2023-01-31
  • 1970-01-01
  • 2014-09-10
  • 2020-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多