empirically
. 这个
assoc
在里面
insert!
为了让测试更清晰,我把备忘录改成了
在两个电话之间共用一张桌子。
#lang r5rs
(#%require srfi/19)
(define false #f)
(define true #t)
(define (memoize f)
(let ((table (make-table)))
(lambda (x)
(let ((previously-computed-result
(lookup x table)))
(or previously-computed-result
(let ((result (f x)))
(insert! x result table)
result))))))
(define (lookup key table)
(let ((record (assoc key (cdr table))))
(if record
(cdr record)
false)))
(define (assoc key records)
(cond ((null? records) false)
((equal? key (caar records))
(car records))
(else (assoc key (cdr records)))))
(define (insert! key value table)
(let ((record #f ; NB
; (assoc key (cdr table)) ; NB
))
(if record
(set-cdr! record value)
(set-cdr! table
(cons (cons key value)
(cdr table)))))
'ok)
(define (make-table)
(list '*table*))
(define memo-fib
(lambda (n)
(letrec ((mf (memoize ; NB
(lambda (n)
(cond ((= n 0) 0)
((= n 1) 1)
(else
(+ (mf (- n 1))
(mf (- n 2)))))))))
(mf n))))
(define (tt n)
(let* ((t1 (current-time))
(f (memo-fib n))
(t2 (current-time))
(td (time-difference t2 t1))
(n (time-nanosecond td)))
(/
(+ (* (time-second td) 1000000000)
n)
1000000.0))) ; time in milliseconds
; > (memo-fib 100)
; 354224848179261915075
(define (tt2 n1 n2)
(let* ((t1 (tt n1))
(t2 (tt n2)))
(values t1 t2
(cond ((> t1 0)
(/ (log (/ t2 t1)) (log (/ n2 n1))))))))
测试是以一种非常初级的方式进行的。时间以毫秒为单位。
; with the lookup in insert!:
; n1 n2 t1 t2 a in t ~ n^a, empirically
; > (tt2 2000 3000) ;=> 90.0 200.0 1.96936
; > (tt2 2000 3000) ;=> 100.0 220.0 1.94457
; > (tt2 2000 3000) ;=> 90.0 210.0 2.08969
; without the lookup: 80,000 takes under 1 second
; but run times are wildly erratic
所以这看起来确实像是作者的疏忽,他们使用的是一般的
插入!
知道
我们只插入
新的
因为我们
记忆化
首先是功能!
所以,
insert-new!
:
(define (memoize f)
(let ((table (make-table)))
(lambda (x)
(let ((previously-computed-result
(lookup x table)))
(or previously-computed-result
(let ((result (f x)))
(insert-new! x result table)
result))))))
(define (insert-new! key value table)
(set-cdr! table
(cons (cons key value)
(cdr table)))
'ok)
然后是
应该
变成线性。