2014-04-04 8 views
5

1 + 1/2 + 1/3 + ... + 1/100000000의 합계를 계산하고 싶습니다 (double float 사용).이 라켓 코드를 최적화하는 방법은 무엇입니까?

SBCL와

,이 코드는 C에서와 같이 빠른 실행 :

(loop for i fixnum from 1 to 100000000 sum (/ 1.0d0 i) double-float) 

어떻게 형식화 된 라켓이 코드를 최적화 할 수 있습니다? 시도했습니다.

#lang typed/racket 

(define: (test) : Float 
     (for/fold: : Float 
        ([s : Float 0.0]) 
        ([i : Fixnum (in-range 1 100000001)]) 
        (+ s (/ 1.0 i)))) 

(time (test)) 

이 코드는 유형이없는 것보다 약간 빠릅니다. 더 가도 될까요?

+4

한 빠른 제안은 ['최적화-coach' 패키지]를 시도하는 것입니다 (https://github.com/stamourv/optimization-coach/tree/master). –

답변

7

Greg가 제안한 것처럼 Optimization Coach를 실행하면 / 함수가 fixnum 및 flonum에서 혼합 산술을 수행하기 때문에 루프 본문이 느리다는 것을 즉시 알립니다. i 대신 (fx->fl i)을 삽입하면 속도가 빨라집니다 (내 컴퓨터에서 2 배 가까이). 당신이 DrRacket이 타이밍 경우 또한

, 대신 racket 실행 파일을 시간이하고자하는 것입니다. DrRacket은 개발 중에 도움이되는 디버깅 도구를 추가하지만 타이밍에는 좋지 않습니다.

+4

'exact-> inexact' 또는'사용하여 안전하지 않은-fx-> fl'는 인수가 실제로 Fixnum이라는 것을 확인 생략하기 때문에 fx-> fl' 다른 ~ 30 %의 속도 향상을 제공하는 대신'의. – stchang

+4

또한 일부 예비 벤치마킹은이 프로그램의 최적화 된 Typed Racket 코드가 SBCL보다 ~ 10 % 빠르다는 것을 나타냅니다. – stchang

2

여기에 내가 수레를 합산위한 작은 도우미 매크로를 제작하는 새로운 버전입니다.

#lang typed/racket 

(require syntax/parse/define) 

(define-simple-macro (for/flsum x ... (c ...) b ... e) 
    (for/fold : Float x ... ([s 0.0]) (c ...) b ... (+ s e))) 

(time (for/flsum ([i : Positive-Fixnum (in-range 1 100000001)]) (/ 1.0 i))) 

주 그 종류는 우리가 추가 변환이 필요하지 않습니다 의미로 Positive-Fixnum를 사용하여 - 형식화 된 라켓은 i 0 결코, 그래서 / 항상 최적화 할 수 있다는 것을 알고있다. 이제는 내 컴퓨터에서 SBCL만큼 빠르게 실행됩니다. 예외를 제기 라켓은에 +inf.0를 생성하는 반면 -

그것과 SBCL 코드 사이의 유일한 차이점은 Fixnum이라는가 SBCL가 (/ 1.0 0)(/ 1.0 0.0) 대해 동일한 의미를 가지고 있기 때문에 요구되는 긍정적 인 것을 지정할 필요가있다 두 번째 경우와 첫 번째 경우의 예외가 있습니다.

나는 그 자체를 라켓을 같이 for/flsum 또는 무언가를 추가 할 계획입니다.

관련 문제