## 6 Profiling

MIT/GNU Scheme provides a simple-minded statistical profiler called the stack sampler, which periodically interrupts the program and records the return addresses that it finds on the stack. For each return address, the stack sampler records two counts: the number of times that return address was at the top of the stack, called the sampled count, and the number of times that return address was somewhere else in the stack, called the waiting count. The topmost ‘return address’ may correspond with a procedure rather than a continuation, if the procedure was about to be called in a tail position when the stack sampler interrupted.

If a return address has a high sampled count, it is in a specific part of the program that may warrant micro-optimization. If a return address has a high waiting count, then the program spends a long time computing the expression for whose value continuations corresponding with the return address are waiting, and the expression may warrant a better algorithm.

The stack sampling is very coarse-grained, because the program is interrupted only at safe points, which are a subset of procedure calls and returns. Another approach to profiling is to record the address of the machine instruction the program is about to have the machine execute, and then to find where in the program that instruction is. This could provide finer-grained sampled counts, but it requires a lower-level implementation, and cannot provide waiting counts, because the stack may not be in a consistent, inspectable state except at safe points.

Finally, the stack sampler gives information only about compiled code; it ignores continuations on the stack for interpreted code. This is because continuations for compiled code are easier to deal with, and in any case, if a program is too slow when interpreted, the first step is to compile it, not to profile it.

procedure: with-stack-sampling interval procedure

  Applies procedure to zero arguments. During the dynamic extent of the call to procedure, the stack sampler interrupts the program at intervals of approximately interval milliseconds. When procedure returns, `with-stack-sampling` displays the waiting and sampled counts it gathered.

  More precisely, after each sample, the stack sampler will not sample again before interval milliseconds of real time (in the sense of `real-time-clock`; see Machine Time in MIT/GNU Scheme Reference Manual) have elapsed, although more time may elapse before the next sample.

variable: stack-sampler:show-expressions?

  If true, the output of `with-stack-sampling` shows the subexpression corresponding with each return address, and the expression enclosing it. If false, the output is shorter (one line per return address), and just shows the names of procedures forming the environment hierarchy corresponding with the return address.

variable: stack-sampler:debug-internal-errors?

  If false, the default, errors signalled while recording a sample are ignored. Set this to true only if you are debugging the internals of the system.