単機能ベンチマーク

繰り返し回数を決めて、時間を測るだけというストイックさ。そのくせ複数フォームを渡せるという無駄仕様。

(defmacro benchmark (times &body body)
  (let ((gi (gensym)))
    `(progn
       ,@(mapcar #'(lambda (form)
		     `(progn (print ',form *trace-output*)
			     (time (dotimes (,gi ,times)
				     ,form))
			     (terpri *trace-output*)))
		 body))))


使用例:

CL-USER> (setq lst '(0 1 2 3 4 5 6 7 8 9))
(0 1 2 3 4 5 6 7 8 9)
CL-USER> (benchmark (* 1000 1000)
           (nreverse lst)
           (reverse  lst))

(NREVERSE LST) 
; While compiling (:INTERNAL (:ANONYMOUS-LAMBDA 16) 0):
Warning: Free reference to undeclared variable LST assumed special.
; cpu time (non-gc) 0.031250 sec user, 0.000000 sec system
; cpu time (gc)     0.000000 sec user, 0.000000 sec system
; cpu time (total)  0.031250 sec user, 0.000000 sec system
; real time  0.032000 sec
; space allocation:
;  0 cons cells, 0 other bytes, 0 static bytes


(REVERSE LST) 
; While compiling (:INTERNAL (:ANONYMOUS-LAMBDA 17) 0):
Warning: Free reference to undeclared variable LST assumed special.
; cpu time (non-gc) 0.046875 sec user, 0.000000 sec system
; cpu time (gc)     0.000000 sec user, 0.000000 sec system
; cpu time (total)  0.046875 sec user, 0.000000 sec system
; real time  0.047000 sec
; space allocation:
;  1,000,000 cons cells, 0 other bytes, 0 static bytes