プログラミングGauche メタオブジェクトプロトコル
『プログラミングGauche』17章総称関数とオブジェクトの練習問題をやってみました。
総称関数subは、関数呼び出しの回数と、関数実行にかかった時間を保持する
このままだと、
そこで、
(use gauche.time) (define-class <logger-generic> (<generic>) ((log-on :init-value #t))) (define-method apply-generic ((gf <logger-generic>) args) (if (ref gf 'log-on) (begin (format #t "args: ~s\n" args) (let ((return-values (next-method))) (format #t "result: ~s\n" return-values) return-values)) (next-method))) (define-class <profiler-generic> (<logger-generic>) ((counter :init-value 0) (time :init-form (make <real-time-counter>)))) (define-method apply-generic ((gf <profiler-generic>) args) (inc! (ref gf 'counter)) (with-time-counter (ref gf 'time) (next-method))) (define-method get-profiles ((gf <profiler-generic>)) (format #t "~s: ~d times called and spent time ~d\n" (ref gf 'name) (ref gf 'counter) (time-counter-value (ref gf 'time)))) (define-method init-profile ((gf <profiler-generic>)) (set! (ref gf 'counter) 0) (set! (ref gf 'time) (make <real-time-counter>))) (define-generic sub :class <profiler-generic>) (define-method sub ((num1 <number>) (num2 <number>)) (- num1 num2))
以下のように使います。
gosh> (get-profiles sub) sub: 0 times called and spent time 0 #<undef> gosh> (define val (with-output-to-string (lambda () (map sub (iota 10000 100 3) (iota 10000 300 5))))) val gosh> (get-profiles sub) sub: 10000 times called and spent time 1.3829899999999549 #<undef> gosh> (init-profile sub) #<undef> gosh> (get-profiles sub) sub: 0 times called and spent time 0 #<undef> gosh> (set! (ref sub 'log-on) #f) #<undef> gosh> (define val (with-output-to-string (lambda () (map sub (iota 10000 100 3) (iota 10000 300 5))))) val gosh> (get-profiles sub) sub: 10000 times called and spent time 0.182114999999972 #<undef>