2012-07-21 6 views
3

지금까지 동일한 함수를 작성하는 여러 접근법의 속도를 테스트하면서 나는 time 함수를 사용하고 있었으며 일반적으로 다른 함수의 상대적 속도를 잘 보여줍니다 이들은 일반적으로 약 100k 사이클 차이가 있기 때문에).Lisp : 함수의 성능 측정

그러나 factorial 기능에 대한 가장 빠른 방법을 찾으려고 시도했지만 time은 부족했습니다. 이러한 방법은 단지 10k-30k주기 만 다를뿐 아니라 전체 시간도 약 절반 정도 차이가납니다 (예상되는 것 같습니다).

factorial 기능 :) 어떤 사실 인 경우 (

1) 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))))) 

는, 나는이 개 질문이 됐을까?

2.) 내가 일반적인 방법으로 더 빠른 기능을 찾았다면 무엇을 할 수있는 가장 좋은 방법이 될까요 (LOC가 속도의 나쁜 지표라고 생각합니다). 아마도 Lisp 바이트 코드의 디스 어셈블리를 보는 방법이 있을까요? 아니면 더 나은, 더 엄격한 방법이 있을까요?

저는 현재 Linux 3.2.0-26, SBCL을 Ubuntu 12.04 x86-64에서 실행하고 있습니다.

+0

사용중인 CL의 구현은 무엇입니까? – JasonFruit

+0

죄송합니다. SBCL을 사용하고 있습니다. – Soyuz

답변

5

SBCL이 '바이트 코드'로 컴파일되지 않습니다. 네이티브 머신 코드로 컴파일됩니다.

DISASSEMBLE을 사용하여 Lisp 함수를 디스 어셈블 할 수 있습니다.

숫자가 bignum 범위에 들어가면 계승 함수의 속도가 bignum 산술 곱셈에 의해 지배됩니다.

당신이 사용하는 반복 구조 DO 또는 LOOP는별로 중요하지 않습니다. 대부분의 시간은 bignums를 곱하는 데 소비됩니다. 재귀 버전은 많은 차이를 만들지 않습니다.

이는 일반적인 벤치 마크 문제입니다. 많은 간단한 숫자 벤치 마크는 bignum의 곱셈과 같은 몇 가지 산술 연산의 런타임에 의해 지배됩니다. 그들은 다양한 종류의 제어 흐름과 같은 일반적인 언어 작업 속도의 차이를 상당 부분 측정하지 않습니다.

빠른 bignum 라이브러리를 사용하는 느린 Lisp은 Bignum 코드가 Lisp로 작성된 최적화 Lisp 컴파일러보다 빠를 가능성이 높습니다.

+0

오 이런, 나는 거기에 버렸다. 처음에 나는 (그리고 (...) (해결책을 돌려 준다)) 썼다. 그러나 나는 그것이 어리석은 것을 깨달았다. 해체는 내가 필요로하는 것처럼 보인다. 그래서 나는 그것을 또한 성과를 측정하는 가장 좋은 방법으로 모으는가? 스트레이트가 있다고 생각 하는가? 내 첫 번째 질문에 대한 답변? 감사합니다! – Soyuz