comparison lisp/prim/profile.el @ 207:e45d5e7c476e r20-4b2

Import from CVS: tag r20-4b2
author cvs
date Mon, 13 Aug 2007 10:03:52 +0200
parents 850242ba4a81
children
comparison
equal deleted inserted replaced
206:d3e9274cbc4e 207:e45d5e7c476e
24 24
25 ;;; Synched up with: Not in FSF. 25 ;;; Synched up with: Not in FSF.
26 26
27 ;;; Commentary: 27 ;;; Commentary:
28 28
29 ;; In addition to Lisp-based `elp', XEmacs contains a set of 29 ;; In addition to Lisp-based `elp', XEmacs provides a set of
30 ;; primitives able to profile evaluation of Lisp functions, created by 30 ;; primitives able to profile evaluation of Lisp functions, created by
31 ;; the illustrious Ben Wing. The functions in this file can be used 31 ;; the illustrious Ben Wing. The functions in this file can be used
32 ;; to gain easy access to the internal profiling functions. 32 ;; to gain easy access to the internal profiling functions.
33 33
34 ;; The profiler works by catching "ticks" (actually SIGPROF signals), 34 ;; The profiler works by catching "ticks" (actually SIGPROF signals),
35 ;; and looking at the current Lisp function, at the time of each tick. 35 ;; and looking at the current Lisp function, at the time of each tick.
36 ;; The output of this process is an alist with keys being the 36 ;; The output of this process is an alist with keys being the
37 ;; functions, and values being the number of ticks per function. From 37 ;; functions, and values being the number of ticks per function. From
38 ;; this, `profiling-results' easily extracts the total number of 38 ;; this, `profiling-results' easily extracts the total number of
39 ;; ticks, and the percentage CPU time of each function. 39 ;; Unless stated otherwise, profiling info is being accumulated
40 40 ;; incrementally through several profile runs (the current info is
41 ;; Unless stated otherwise, profiling info is being accumulated (the 41 ;; always available by `get-profiling-info'). Use
42 ;; current info is returned by `get-profiling-info'). Use
43 ;; `clear-profiling-info' to break the accumulation chain. 42 ;; `clear-profiling-info' to break the accumulation chain.
44 43
45 ;; Caveats (ELP users should read this): 44 ;; Caveats (ELP users should read this):
46 ;; 1) The time reported is function time, rather than 45 ;; 1) The time reported is function time, rather than
47 ;; function+descendants time; 46 ;; function+descendants time;
48 ;; 2) The Time/ms is CPU time (user+kernel), not the real time; 47 ;; 2) Each tick is equivalent to 1ms (which can be changed), but this
48 ;; is CPU time (user+kernel), not the real time;
49 ;; 3) Only the actuall funcalls are profiled. If a subr Ffoo calls 49 ;; 3) Only the actuall funcalls are profiled. If a subr Ffoo calls
50 ;; Fbar using Fbar (), only Ffoo will appear in the profile. 50 ;; Fbar using Fbar (), only Ffoo will appear in the profile.
51 51
52 ;; A typical profiling session consists of using `clear-profiling-info' 52 ;; A typical profiling session consists of using `clear-profiling-info'
53 ;; followed by `profile' or `profile-key-sequence', followed by 53 ;; followed by `profile' or `profile-key-sequence', followed by
57 ;; buffer, go to the group buffer, and press `M-x clear-profiling-info' 57 ;; buffer, go to the group buffer, and press `M-x clear-profiling-info'
58 ;; followed by `M-x profile-key-sequence RET SPC'. 58 ;; followed by `M-x profile-key-sequence RET SPC'.
59 59
60 60
61 ;;; Code: 61 ;;; Code:
62
63 (defun profile-align (form width)
64 ;; Bletch! this is what (format "%-*s" width form) should do.
65 (let ((printed-form (format "%s" form)))
66 (concat printed-form
67 (make-string (max 0 (- width (length printed-form))) ?\ ))))
68 62
69 ;;;###autoload 63 ;;;###autoload
70 (defun profile-results (&optional info stream) 64 (defun profile-results (&optional info stream)
71 "Print profiling info INFO to STREAM in a pretty format. 65 "Print profiling info INFO to STREAM in a pretty format.
72 If INFO is omitted, the current profiling info is retrieved using 66 If INFO is omitted, the current profiling info is retrieved using
86 (current-buffer) 80 (current-buffer)
87 standard-output))) 81 standard-output)))
88 ;; Calculate the longest function 82 ;; Calculate the longest function
89 (maxfunlen (apply #'max 83 (maxfunlen (apply #'max
90 (length "Function Name") 84 (length "Function Name")
91 (mapcar (lambda (el) 85 (mapcar
92 ;; Functions longer than 40 86 (lambda (el)
93 ;; characters don't qualify 87 ;; Functions longer than 50 characters (usually
94 (let ((l (length (format "%s" (car el))))) 88 ;; anonymous functions) don't qualify
95 (if (< l 40) 89 (let ((l (length (format "%s" (car el)))))
96 l 0))) 90 (if (< l 50)
97 info)))) 91 l 0)))
98 (princ (format "%s Ticks %%/Total\n" 92 info))))
99 (profile-align "Function Name" maxfunlen))) 93 (princ (format "%-*s Ticks %%/Total\n" maxfunlen "Function Name"))
100 (princ (make-string maxfunlen ?=)) 94 (princ (make-string maxfunlen ?=))
101 (princ " ===== =======\n") 95 (princ " ===== =======\n")
102 (let ((sum (float (apply #'+ (mapcar #'cdr info))))) 96 (let ((sum (float (apply #'+ (mapcar #'cdr info)))))
103 (dolist (entry (nreverse (sort info #'cdr-less-than-cdr))) 97 (dolist (entry (nreverse (sort info #'cdr-less-than-cdr)))
104 (princ (format "%s %-5d %-6.3f\n" 98 (princ (format "%-*s %-5d %-6.3f\n"
105 (profile-align (car entry) maxfunlen) 99 maxfunlen (car entry) (cdr entry)
106 (cdr entry) (* 100 (/ (cdr entry) sum))))) 100 (* 100 (/ (cdr entry) sum)))))
107 (princ (make-string maxfunlen ?-)) 101 (princ (make-string maxfunlen ?-))
108 (princ "--------------------\n") 102 (princ "--------------------\n")
109 (princ (format "%s %-5d %-6.2f\n" 103 (princ (format "%-*s %-5d %-6.2f\n" maxfunlen "Total" sum 100.0))
110 (profile-align "Total" maxfunlen) sum 100.0))
111 (princ (format "\n\nOne tick = %g ms\n" 104 (princ (format "\n\nOne tick = %g ms\n"
112 (/ default-profiling-interval 1000.0))))) 105 (/ default-profiling-interval 1000.0)))))
113 (when (and (not stream) 106 (when (and (not stream)
114 (interactive-p)) 107 (interactive-p))
115 (goto-char (point-min)))) 108 (goto-char (point-min))))