2016/02/10
SICP 問題 5.46
5.45と同様に今度はフィボナッチ数列の計算でそれぞれ比べる.
gosh> (define fib ;;一回目以外は省略
(make-machine
(list (list '< <)
(list '- -)
(list '+ +))
'(controller
(assign continue (label fib-done))
fib-loop
(test (op <) (reg n) (const 2))
(branch (label immediate-answer))
;; Fib(n-1)を計算するよう設定
(save continue)
(assign continue (label afterfib-n-1))
(save n) ;n の昔の値を退避
(assign n (op -) (reg n) (const 1)) ;n を n-1 に変える
(goto (label fib-loop)) ;再帰呼び出しを実行
afterfib-n-1 ;戻った時 Fib(n-1) は val にある
(restore n)
(restore continue)
;; Fib(n-2)を計算するよう設定
(assign n (op -) (reg n) (const 2))
(save continue)
(assign continue (label afterfib-n-2))
(save val) ;Fib(n-1) を退避
(goto (label fib-loop))
afterfib-n-2 ;戻った時 Fib(n-2) の値は val にある
(assign n (reg val)) ;n には Fib(n-2) がある
(restore val) ;val には Fib(n-1) がある
(restore continue)
(assign val ;Fib(n-1) + Fib(n-2)
(op +) (reg val) (reg n))
(goto (reg continue)) ;呼び出し側に戻る.答えは val にある
immediate-answer
(assign val (reg n)) ;基底の場合: Fib(n)=n
(goto (reg continue))
fib-done
(perform (op print-stack-statistics)))))
fib
gosh> (set-register-contents! fib 'n 1)
done
gosh> (start fib)
(total-pushes = 0 maximum-depth = 0)done
gosh> (get-register-contents fib 'val)
1
gosh> (set-register-contents! fib 'n 2)
done
gosh> (start fib)
(total-pushes = 4 maximum-depth = 2)done
gosh> (get-register-contents fib 'val)
1
gosh> (set-register-contents! fib 'n 3)
done
gosh> (start fib)
(total-pushes = 8 maximum-depth = 4)done
gosh> (get-register-contents fib 'val)
2
gosh> (set-register-contents! fib 'n 4)
done
gosh> (start fib)
(total-pushes = 16 maximum-depth = 6)done
gosh> (get-register-contents fib 'val)
3
gosh> (set-register-contents! fib 'n 5)
done
gosh> (start fib)
(total-pushes = 28 maximum-depth = 8)done
gosh> (get-register-contents fib 'val)
5
gosh> (set-register-contents! fib 'n 5)
done
gosh> (start fib)
(total-pushes = 28 maximum-depth = 8)done
gosh> (get-register-contents fib 'val)
5
gosh> (set-register-contents! fib 'n 6)
done
gosh> (start fib)
(total-pushes = 48 maximum-depth = 10)done
gosh> (get-register-contents fib 'val)
8
gosh> (set-register-contents! fib 'n 7)
done
gosh> (start fib)
(total-pushes = 80 maximum-depth = 12)done
gosh> (get-register-contents fib 'val)
13
gosh> (set-register-contents! fib 'n 8)
done
gosh> (start fib)
(total-pushes = 132 maximum-depth = 14)done
gosh> (get-register-contents fib 'val)
21
gosh> (set-register-contents! fib 'n 9)
done
gosh> (start fib)
(total-pushes = 216 maximum-depth = 16)done
gosh> (get-register-contents fib 'val)
34
gosh> (set-register-contents! fib 'n 10)
done
gosh> (start fib)
(total-pushes = 352 maximum-depth = 18)done
gosh> (get-register-contents fib 'val)
55
翻訳系
gosh> (compile-and-go
'(define (fib n)
(if (< n 2)
n
(+ (fib (- n 1)) (fib (- n 2))))))
(total-pushes = 0 maximum-depth = 0)
;;; EC-Eval value:
ok
;;; EC-Eval input:
(fib 1)
(total-pushes = 7 maximum-depth = 3)
;;; EC-Eval value:
1
;;; EC-Eval input:
(fib 2)
(total-pushes = 15 maximum-depth = 5)
;;; EC-Eval value:
1
;;; EC-Eval input:
(fib 3)
(total-pushes = 23 maximum-depth = 7)
;;; EC-Eval value:
2
;;; EC-Eval input:
(fib 4)
(total-pushes = 39 maximum-depth = 9)
;;; EC-Eval value:
3
;;; EC-Eval input:
(fib 5)
(total-pushes = 63 maximum-depth = 11)
;;; EC-Eval value:
5
;;; EC-Eval input:
(fib 6)
(total-pushes = 103 maximum-depth = 13)
;;; EC-Eval value:
8
;;; EC-Eval input:
(fib 7)
(total-pushes = 167 maximum-depth = 15)
;;; EC-Eval value:
13
;;; EC-Eval input:
(fib 8)
(total-pushes = 271 maximum-depth = 17)
;;; EC-Eval value:
21
;;; EC-Eval input:
(fib 9)
(total-pushes = 439 maximum-depth = 19)
;;; EC-Eval value:
34
;;; EC-Eval input:
(fib 10)
(total-pushes = 711 maximum-depth = 21)
;;; EC-Eval value:
55
積極制御評価器
;;; EC-Eval input:
(define (ec-fib n)
(if (< n 2)
n
(+ (ec-fib (- n 1)) (ec-fib (- n 2)))))
(total-pushes = 3 maximum-depth = 3)
;;; EC-Eval value:
ok
;;; EC-Eval input:
(ec-fib 1)
(total-pushes = 16 maximum-depth = 8)
;;; EC-Eval value:
1
;;; EC-Eval input:
(ec-fib 2)
(total-pushes = 72 maximum-depth = 13)
;;; EC-Eval value:
1
;;; EC-Eval input:
(ec-fib 3)
(total-pushes = 128 maximum-depth = 18)
;;; EC-Eval value:
2
;;; EC-Eval input:
(ec-fib 4)
(total-pushes = 240 maximum-depth = 23)
;;; EC-Eval value:
3
;;; EC-Eval input:
(ec-fib 5)
(total-pushes = 408 maximum-depth = 28)
;;; EC-Eval value:
5
;;; EC-Eval input:
(ec-fib 6)
(total-pushes = 688 maximum-depth = 33)
;;; EC-Eval value:
8
;;; EC-Eval input:
(ec-fib 7)
(total-pushes = 1136 maximum-depth = 38)
;;; EC-Eval value:
13
;;; EC-Eval input:
(ec-fib 8)
(total-pushes = 1864 maximum-depth = 43)
;;; EC-Eval value:
21
;;; EC-Eval input:
(ec-fib 9)
(total-pushes = 3040 maximum-depth = 48)
;;; EC-Eval value:
34
;;; EC-Eval input:
(ec-fib 10)
(total-pushes = 4944 maximum-depth = 53)
;;; EC-Eval value:
55
プッシュ数
| n | 計算機 | 翻訳系 | 評価器 | 評/機 | 翻/機 |
|---|---|---|---|---|---|
| 3 | 8 | 23 | 128 | 16.0 | 2.87 |
| 4 | 16 | 39 | 240 | 15.0 | 2.43 |
| 5 | 28 | 63 | 408 | 14.57 | 2.25 |
| 6 | 48 | 103 | 688 | 14.33 | 2.14 |
| 7 | 80 | 167 | 1136 | 14.2 | 2.08 |
| 8 | 132 | 271 | 1864 | 14.12 | 2.05 |
| 9 | 216 | 439 | 3040 | 14.07 | 2.03 |
| 10 | 352 | 711 | 4944 | 14.04 | 2.01| |
| 20 | 43780 | 87567 | 612936 | 14.0 | 2.0 |
最大スタック深さ
| 計算機 | 翻訳系 | 評価器 | 評/機 | 翻/機 |
|---|---|---|---|---|
| 2n-2 | 2n+1 | 5n+3 | 2.500 | 1.00 |