2 ;; Copyright (C) 2007 Sebastian Freundt
4 ;; Author: Sebastian Freundt <hroptatyr@sxemacs.org>
5 ;; Keywords: profiling, benchmark
7 ;; This file is part of SXEmacs.
9 ;; Redistribution and use in source and binary forms, with or without
10 ;; modification, are permitted provided that the following conditions
13 ;; 1. Redistributions of source code must retain the above copyright
14 ;; notice, this list of conditions and the following disclaimer.
16 ;; 2. Redistributions in binary form must reproduce the above copyright
17 ;; notice, this list of conditions and the following disclaimer in the
18 ;; documentation and/or other materials provided with the distribution.
20 ;; 3. Neither the name of the author nor the names of any contributors
21 ;; may be used to endorse or promote products derived from this
22 ;; software without specific prior written permission.
24 ;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
25 ;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 ;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 ;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 ;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 ;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 ;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
31 ;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32 ;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
33 ;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
34 ;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 ;;; Synched up with: Not in FSF.
40 (defmacro bm-profile-time-ord (&rest body)
41 `(let ((sttb (current-time)))
43 (time-subtract (current-time) sttb)))
45 (defmacro bm-profile-time-multi-ord (count &rest body)
47 (sttb (current-time)))
51 (time-subtract (current-time) sttb)))
54 (defmacro bm-profile-time-btime (&rest body)
55 `(let* ((none (garbage-collect))
56 (sttb (current-btime)))
58 (- (current-btime) sttb)))
60 (defmacro bm-profile-time-multi-btime (count &rest body)
62 (sttb (current-btime)))
63 (while (nonnegativep cnt)
66 (- (current-btime) sttb)))
69 (cond ((fboundp #'current-btime)
70 (defalias 'bm-profile-time 'bm-profile-time-btime)
71 (defalias 'bm-profile-time-multi 'bm-profile-time-multi-btime))
72 ((fboundp #'time-subtract)
73 (defalias 'bm-profile-time 'bm-profile-time-ord)
74 (defalias 'bm-profile-time-multi 'bm-profile-time-multi-ord))
77 (put 'bm-profile-time 'lisp-indent-function 'defun)
78 (put 'bm-profile-time-multi 'lisp-indent-function 'defun)
81 (defun bm-compute-sample-points (test-range &optional grain)
82 (let* ((lo (car test-range))
84 (grain-ratio (// hi lo grain))
87 (step (// (- hi lo) grain))
88 (stepl (// (- hil lol) grain))
89 (i (coerce-number lol 'int))
90 (logp (> grain-ratio 1))
91 (result (make-vector (1+ grain) nil))
95 (let* ((exp (exp lol))
96 (this (coerce-number exp 'int)))
97 (setq lol (+ lol stepl))
101 (let* ((this (coerce-number lo 'int)))
102 (setq lo (+ lo step))
104 (mapc-inplace (if logp #'logf #'linf) result)
107 (defun bm-util-average (dllv c)
108 (let* ((size (dllist-size dllv))
112 (setq res (+ res (aref v c))))
116 (defun bm-util-deviation (dllv avg c)
117 (let* ((size (dllist-size dllv))
122 (+ res (^ (- (aref v c) avg) 2))))
124 (sqrt (// res size))))
126 (defun bm-determine-time-stability (test-funv result)
127 "Examine RESULT and try to guess if time data behaves like O(1)."
128 (let* ((vlen (length test-funv))
129 (resv (make-vector (1+ vlen) 0))
134 (let* ((fun (aref test-funv j))
135 (name (function-documentation fun))
136 (avg (bm-util-average result j))
137 (adev (bm-util-deviation result avg j))
138 (rdev (* (// adev avg) 100)))
139 (setq avgsum (+ avgsum avg)
140 devsum (+ devsum adev))
141 (aset resv j (vector name avg adev rdev)))
143 (aset resv vlen (vector "SUM" avgsum devsum (* (// devsum avgsum) 100)))
146 (defun bm-examine-time-stability (test-funv point)
147 (princ (format "Testing time stability on %d ...\n" point)
148 'external-debugging-output)
151 (loop for i below grain
156 (insert (format "%d" point))
163 (insert (format " %d" time))
167 (insert (format "\n" point)))))
168 (let* ((ts (bm-determine-time-stability test-funv pile)))
169 ;;(bm-dump-pile test-funv pile ts)
172 (let* ((name (aref v 0))
176 (princ (format "%32s, avg: %10d us (±%d us = %3.2f %%%s)\n"
178 (if (< rdev 25) "" " = UNSTABLE!"))
179 'external-debugging-output)))
183 (defun bm-run-tests (test-funv point)
184 (bm-examine-time-stability test-funv point))
186 (defun bm-estimate-time (test &optional grain)
187 (let* ((test-funv (plist-get test :test-funv))
188 (test-range (plist-get test :test-range))
189 (grain (or grain (plist-get test :grain) 20))
190 (pf (plist-get test :plot-file))
191 (buf (get-buffer-create (or pf "dontcare")))
192 (tflen (length test-funv))
193 (sample-points (bm-compute-sample-points test-range grain))
194 (samples (make-skiplist)))
198 (loop for j from 1 to tflen
199 do (insert (format " t%d" j)))
204 (put-skiplist samples point (bm-run-tests test-funv point)))
206 (write-region-internal (point-min) (point-max) pf)
207 (princ "\n" 'external-debugging-output))
211 (defun bm-plot-samples-comp (samples c buf)
212 ;; samples is a vector consisting of a pile and an estimation?
213 (with-current-buffer (get-buffer-create buf)
214 (insert (format "\n### component %d\n" c))
217 (let* ((pile (aref val 0))
221 (insert (format "%d %f %f %f\n"
222 key (aref vec 1) (aref vec 2) (aref vec 3)))))
226 (defun bm-dump-samples (samples buf)
227 ;; samples is a vector consisting of a pile and an estimation?
228 (with-current-buffer (get-buffer-create buf)
231 (insert (format "%s %S\n" key val)))
235 (defun bm-dump-pile (test-funv pile ts)
237 (let* ((vlen (length test-funv))
238 (resv (make-vector (1+ vlen) 0))
241 (let* ((fun (aref test-funv j))
242 (name (function-documentation fun))
244 (insert "\n\n## " name "\n")
247 (insert (format "%d %f\n" i (aref v j)))
251 (write-region (point-min) (point-max) "benchmark.plot")
252 (princ "\n" 'external-debugging-output))))