Gauche と速度比較 3題 - Scheme VM を書く

さあ比較してみよう。

計測条件

  • X60 Core2 Duo
  • Linux 2.6.22-14-generic #1 SMP
  • Gauche は version 0.8.13 [utf-8,pthreads]
  • 自前処理系は r5198
    • gcc (GCC) 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)
    • -O2 -fomit-frame-pointer

計測結果

計測項目 Gauche 自前
fib 140ms 330ms
tak 40ms 30ms
case 150ms 210ms

tak だけは自前の方が速いです。display クロージャ効果かしら。(決めつけは禁物。)
これからどれだけ改善されるか楽しみですね!


コンパイルと eval の割合を追加で計測。単位は micro sec.

項目 compile eval
fib 1129 279278
tak 3702 28557
case 1551 243881

短いコードだとコンパイルはそこまで遅くないな。

コード

SigScheme の bench を参考にさせていただきました。

fib
(define (fib n)
  (if (<= n 2) 1
      (+ (fib (- n 1)) (fib (- n 2)))))
(write (fib 30))
(display "  :")
tak
(define (cpstak x y z)
  (define (tak x y z k)
    (if (not (< y x))
        (k z)
        (tak (- x 1)
             y
             z
             (lambda (v1)
               (tak (- y 1)
                    z
                    x
                    (lambda (v2)
                      (tak (- z 1)
                           x
                           y
                           (lambda (v3)
                             (tak v1 v2 v3 k)))))))))
  (tak x y z (lambda (a) a)))
(write (cpstak 18 12 6))
(display "  :")
case
(define (loop i l)
  (case 6
    ((1 2 3 4 5) #f)
    ((6)
     (if (< i l)
         (loop (+ 1 i) l)
         l))))
(write (loop 0 500000))
(display "  :")

追記

意図的な長めのコードも試した。

(define a 100)
(write (let1 a1 a
         (let1 a2 a
           (let1 a3 a
             (let1 a4 a
               (let1 a5 a
                 (let1 a6 a
                   (let1 a7 a
                     (let1 a8 a
                       (let1 a9 a
                         (let1 a10 a
                           (let1 a11 a
                             (let1 a12 a
                               (let1 a13 a
                                 (let1 a14 a
                                   (let1 a15 a
                                     (let1 a16 a
                                       (let1 a17 a
                                         (let1 a18 a
                                           (let1 a19 a
                                             (let1 a20 a
                                               (let1 a21 a
                                                 (let1 a22 a
                                                   (let1 a23 a
                                                     (let1 a24 a
                                                       (let1 a25 a
                                                         (let1 a26 a
                                                           (let1 a27 a
                                                             (let1 a28 a
                                                               (let1 a29 a
                                                                 (let1 a30 a
                                                                   (+ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 a21 a22 a23 a24 a25 a26 a27 a28 a29))))))))))))))))))))))))))))))))
COMPILE = 50764  EVAL=55

この件はデータ不足なのでまずは fib の eval ループに着手する。

次の一手

fib 実行時に呼ばれるインストラクション毎の回数・かかる時間を調べる。