5.3.3 The performance monitor

5.3.3.1 Using the performance monitor

Before you can monitor your code, you should make certain that it executes correctly; entering the Debugger disables monitoring. You should also compile your code before attempting to monitor it. Though you can use the Performance Monitor in an interpreted environment, the results are not meaningful because they are influenced by the overhead of the Interpreter. You can get the most information from the Performance Monitor if your code is compiled using the production mode of the Compiler.

To use the Performance Monitor, follow these steps:

1. Compile the code in the production mode of the Compiler. The following form invokes the production mode of the Compiler:

(proclaim '(optimize (speed 3) (safety 1) 
                     (compilation-speed 0)))
2. Call the macro monitor or the function monitor-functions with the names of the functions you want to monitor as arguments. By default, monitoring occurs in all processes except the idle process.

3. Call the function start-monitoring to begin collecting information for the functions.

4. Execute the code normally.

5. Call the function stop-monitoring to disable monitoring while keeping the state of the Performance Monitor intact. You can then resume monitoring in this state at a later time.

6. Call a reporting function, such as print-monitor or summarize-monitors, to examine the results.

7. Remove the Performance Monitor from the functions by calling the macro unmonitor or the function unmonitor-functions.

You cannot use the Performance Monitor at the same time that you are using the Backtrace Logging Facility. See the section "The Backtrace Logging Facility" for a description of this tool.

Normally the information gathered by the Performance Monitor is sent to the terminal screen. If you would prefer to capture this information in a file, you can use the function print-monitor or print-monitors to direct the output to a stream of your choosing.

For example, the filebinomial.lisp contains these function definitions:

;;; FACT is the factorial function n!. 
(defun fact (n) 
	(if (< n 2) 1 (* n (fact (1- n))))) 

;;; PERM is the permutation function P(n,k) = n!/(n-k)!. 
(defun perm (n k) 
	(if	(<= 0 k n) 
	(do* ((i (- n k) (1+ i)) 
	(x 1 (* x i))) 
	 ((>= i n) x)) 
	0)) 

;;; CHOOSE returns the binomial coefficient C(n,k) = P(n,k)/k!. 
;;; This is the coefficient of x^k in the expansion of (x+1)^n. (defun choose (n k) 
	(/ (perm n k) (fact k))) 

;;; BINOMIAL-COEFFICIENTS returns a list of the binomial 
;;; coefficients for the nth order equation. 
(defun binomial-coefficients (n) 
	(let ((result nil)) 
	(dotimes (k (1+ n) result) 
	(push (choose n k) result)))) 

The following example monitors a call to the functions choose, fact, and perm from this file and sends the results to the stream "monitor.output".

> (proclaim '(optimize  (speed 3) (safety 1) 
                        (compilation-speed 0)))
T 
> (load (compile-file "binomial")) 
;;; Reading source file "examples/binomial.lisp" 
;;; Writing binary file "examples/binomial.sbin" 
;;; Loading binary file "examples/binomial.sbin" 
#P"/delivery/binomial.sbin" 

> (monitor choose fact perm) 
(CHOOSE FACT PERM) 
> (start-monitoring) 
T 
> (binomial-coefficients 50) 
(1 50 1225 19600 230300 2118760 15890700 99884400 ...) 
> (stop-monitoring) 
NIL 
> (with-open-file (stream "monitor.output" :direction :output)
	(print-monitors stream)) 
NIL 

The following results are printed to the stream:

 Monitor information for CHOOSE 
Number of calls 	: 51 
Inclusive Time (secs) 	: 0.165 
Exclusive Time (secs) 	: 0.058 
Inclusive Consing (words) 	: 9146
Exclusive Consing (words) 	: 374 
 Monitor information for PERM 
Number of calls 	: 51 
Inclusive Time (secs) 	: 0.068 
Exclusive Time (secs) 	: 0.068 
Inclusive Consing (words) 	: 5124 
Exclusive Consing (words) 	: 5124 
 Monitor information for FACT 
Number of calls 	: 51 
Inclusive Time (secs) 	: 0.039
Exclusive Time (secs) 	: 0.039 
Inclusive Consing (words) 		: 3648 
Exclusive Consing (words) 	: 3648 
 Monitor information for LIQUID:SET-CURRENT-AREA 
Number of calls 	: 41 
Inclusive Time (secs) 	: 0.000 
Exclusive Time (secs) 	: 0.000 
Inclusive Consing (words) 	: 0 
Exclusive Consing (words) 	: 0 

The monitored functions are evaluated in the lexical environment at the time of the call to start-monitoring. Note that only functions and methods can be monitored; special forms cannot be monitored. Calling monitor on a macro is generally not useful.

As the example shows, the function print-monitors prints monitoring information about all monitored functions, including some internal functions of the implementation.

If you are monitoring very small functions that are called often, the timing results might not be accurate. Monitoring small, heavily used functions could also slow down the execution of your code.

The following constructs control the Performance Monitor:

monitor 	                      stop-monitoring
monitor-functions              unmonitor
monitored-processes-predicate 	unmonitor-functions 
reset-monitor 	                with-monitored-definitions 
reset-monitors 	               with-monitoring 
start-monitoring 

The following functions provide information about monitored functions that can be useful if you want to create your own monitor report format:

monitor-exclusive-consing 	    monitoredp 
monitor-exclusive-time 	       print-monitor 
monitor-inclusive-consing 	    print-monitors 
monitor-inclusive-time	        summarize-monitors 
monitor-number-of-calls 


Liquid Common Lisp 5.0 Release and Installation Notes - 9 JUN 1997

Generated with Harlequin WebMaker