Mercurial > hg > xemacs-beta
comparison lisp/prim/profile.el @ 199:169c0442b401 r20-3b26
Import from CVS: tag r20-3b26
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:00:33 +0200 |
parents | 8eaf7971accc |
children | eb5470882647 |
comparison
equal
deleted
inserted
replaced
198:a94d4839ade3 | 199:169c0442b401 |
---|---|
1 ;;; profile.el --- basic profiling commands for XEmacs | 1 ;;; profile.el --- basic profiling commands for XEmacs |
2 | 2 |
3 ;; Copyright (C) 1996 Ben Wing. | 3 ;; Copyright (C) 1996 Ben Wing, (C) 1997 Free Software Foundation. |
4 | 4 |
5 ;; Maintainer: XEmacs Development Team | 5 ;; Maintainer: XEmacs Development Team |
6 ;; Keywords: internal | 6 ;; Keywords: internal |
7 | 7 |
8 ;; This file is part of XEmacs. | 8 ;; This file is part of XEmacs. |
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 ;; `profile' macro and `profile-key-sequence' added in June 1997 by | 29 ;; In addition to Lisp-based `elp', XEmacs contains a set of |
30 ;; hniksic. | 30 ;; primitives able to profile evaluation of Lisp functions, created by |
31 ;; the illustrious Ben Wing. The functions in this file can be used | |
32 ;; to gain easy access to the internal profiling functions. | |
33 | |
34 ;; The profiler works by catching "ticks" (actually SIGPROF signals), | |
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 | |
37 ;; functions, and values being the number of ticks per function. From | |
38 ;; this, `pretty-print-profiling-info' easily extracts the total | |
39 ;; number of ticks, and the percentage CPU time of each function. | |
40 | |
41 ;; Unless stated otherwise, profiling info is being accumulated (the | |
42 ;; current info is returned by `get-profiling-info'). Use | |
43 ;; `clear-profiling-info' to break the accumulation chain. | |
44 | |
45 ;; Caveats (ELP users should read this): | |
46 ;; 1) The time reported is function time, rather than | |
47 ;; function+descendants time; | |
48 ;; 2) The Time/ms is CPU time (user+kernel), not the real time; | |
49 ;; 3) Only the actuall funcalls are profiled. If a subr Ffoo calls | |
50 ;; Fbar using Fbar (), only Ffoo will appear in the profile. | |
51 | |
52 ;; A typical profiling session consists of using `clear-profiling-info' | |
53 ;; followed by `profile' or `profile-key-sequence', followed by | |
54 ;; `pretty-print-profiling-info'. | |
55 | |
56 ;; For instance, to see where Gnus spends time when generating Summary | |
57 ;; buffer, go to the group buffer, and press `M-x clear-profiling-info' | |
58 ;; followed by `M-x profile-key-sequence RET SPC'. | |
31 | 59 |
32 | 60 |
33 ;;; Code: | 61 ;;; Code: |
34 | 62 |
35 ;;;###autoload | 63 ;;;###autoload |
36 (defun pretty-print-profiling-info (&optional info stream) | 64 (defun pretty-print-profiling-info (&optional info stream) |
37 "Print profiling info INFO to STREAM in a pretty format. | 65 "Print profiling info INFO to STREAM in a pretty format. |
38 If INFO is omitted, the current profiling info is retrieved using | 66 If INFO is omitted, the current profiling info is retrieved using |
39 `get-profiling-info'. | 67 `get-profiling-info'. |
40 If STREAM is omitted, either current buffer or standard output are used, | 68 If STREAM is omitted, either a *Profiling Results* buffer or standard |
41 depending on whether the function was called interactively or not." | 69 output are used, depending on whether the function was called |
70 interactively or not." | |
42 (interactive) | 71 (interactive) |
43 (if info | 72 (setq info (if info |
44 (setq info (copy-alist info)) | 73 (copy-alist info) |
45 (setq info (get-profiling-info))) | 74 (get-profiling-info))) |
46 (let ((standard-output (or stream (if (interactive-p) | 75 (when (and (not stream) |
47 (current-buffer) | 76 (interactive-p)) |
48 standard-output)))) | 77 (pop-to-buffer (get-buffer-create "*Profiling Results*")) |
78 (erase-buffer)) | |
79 (let* ((standard-output (or stream (if (interactive-p) | |
80 (current-buffer) | |
81 standard-output))) | |
82 (maxfunlen (max (length "Function Name") | |
83 (apply 'max (mapcar (lambda (sym) | |
84 (length (symbol-name | |
85 (car sym)))) | |
86 info)))) | |
87 (formatstr (format "%%-%ds" maxfunlen))) | |
49 (setq info (nreverse (sort info #'cdr-less-than-cdr))) | 88 (setq info (nreverse (sort info #'cdr-less-than-cdr))) |
50 (princ "Function Count %\n") | 89 (princ (format (concat formatstr " Ticks %%/Total\n") |
51 (princ "---------------------------------------------------------------------\n") | 90 "Function Name")) |
91 (princ (make-string maxfunlen ?=)) | |
92 (princ " ===== =======\n") | |
52 (let ((sum 0.0)) | 93 (let ((sum 0.0)) |
53 (dolist (info2 info) | 94 (dolist (info2 info) |
54 (incf sum (cdr info2))) | 95 (incf sum (cdr info2))) |
55 (while info | 96 (while info |
56 (let ((f (caar info))) | 97 (let ((f (caar info))) |
57 (princ (format "%-50s%10d %6.3f\n" f (cdar info) | 98 (princ (format (concat formatstr " %-5d %-6.3f\n") |
58 (* 100 (/ (cdar info) sum))))) | 99 f (cdar info) (* 100 (/ (cdar info) sum))))) |
59 (pop info))))) | 100 (pop info)) |
101 (princ (make-string maxfunlen ?-)) | |
102 (princ "--------------------\n") | |
103 (princ (format (concat formatstr " %-5d %-6.2f\n") | |
104 "Total" sum 100.0)) | |
105 (princ (format "\n\nOne tick = %g ms\n" | |
106 (/ default-profiling-interval 1000.0))))) | |
107 (when (and (not stream) | |
108 (interactive-p)) | |
109 (goto-char (point-min)))) | |
60 | 110 |
111 ;; Is it really necessary for this to be a macro? | |
61 ;;;###autoload | 112 ;;;###autoload |
62 (defmacro profile (&rest forms) | 113 (defmacro profile (&rest forms) |
63 "Turn on profiling, execute FORMS and restore profiling state. | 114 "Turn on profiling, execute FORMS and restore profiling state. |
64 Profiling state here means that if profiling was not in effect when | 115 Profiling state here means that if profiling was not in effect when |
65 PROFILE was called, it will be turned off after FORMS are evaluated. | 116 PROFILE was called, it will be turned off after FORMS are evaluated. |