2012-07-21 62 views
3

到目前爲止,在測試寫入相同功能的不同方法的速度時,我一直在使用time函數,通常它可以很好地指示不同函數的相對速度(因爲它們通常相差約100k週期)。Lisp:測量功能的性能

雖然試圖找到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。

+0

您使用的CL的實現是什麼? – JasonFruit 2012-07-21 11:48:15

+0

我正在使用SBCL,對不起! – Soyuz 2012-07-21 11:54:44

回答

5

SBCL不會編譯爲'字節碼'。它編譯爲本機機器碼。

您可以使用DISASSEMBLE反彙編Lisp函數。

一旦數字進入高頻範圍,您的階乘函數中的速度就會以數字算術乘法爲主。

爲了讓它更清楚:您使用哪種迭代構造,DO或LOOP,並不重要。大部分時間都花費了倍增。遞歸版本也沒有太大區別。這是一個典型的基準測試問題:很多簡單的數字基準測試都是由幾個算術運算的運行時間(比如倍數)來決定的。他們不會測量一般語言操作的速度差異(如各種控制流程)。

帶有快速bignum庫的緩慢Lisp可能會比使用Lisp編寫Bignum代碼的優化Lisp編譯器更快。

+0

哦,哎呀,我把它留在那裏。起初,我寫了(和......)(返回解決方案),但後來我意識到這是多麼愚蠢,反彙編似乎是我需要的,所以我認爲這也是測量性能的最好方法嗎?回答我的第一個問題?謝謝! – Soyuz 2012-07-21 12:34:26