Gauche と速度比較 3題 - Scheme VM を書く
さあ比較してみよう。
計測条件
計測結果
計測項目 | 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 実行時に呼ばれるインストラクション毎の回数・かかる時間を調べる。