1 Toplevel Interface
profile-thunk
profile
2 Collecting Profile Information
create-sampler
3 Analyzing Profile Data
analyze-samples
profile
node
edge
4 Profile Renderers
4.1 Textual Rendering
render
4.2 Graph Rendering
render
Version: 4.2

Profile: Statistical Profiler

The profile collection implements a statistical profiler. The profiling is done by running a background thread that collects stack snapshots via continuation-mark-set->context, meaning that the result is an estimate of the execution costs and it is limited to the kind of information that continuation-mark-set->context produces (most notably being limited to functions calls, and subject to compiler optimizations); but the result is often useful. In practice, since this method does not require recompilation of your source and has very little runtime overhead, it can be used for longer runs which compensates for these limits.

    1 Toplevel Interface

    2 Collecting Profile Information

    3 Analyzing Profile Data

    4 Profile Renderers

      4.1 Textual Rendering

      4.2 Graph Rendering

1 Toplevel Interface

 (require profile)

This module provides one procedure and one macroxs that are convenient high-level entry points for timing expressions. This hides the details that are available through other parts of the library, and is intended as a convenient tool for profiling code.

(profile-thunk thunk    
  [#:delay delay    
  #:repeat iterations    
  #:threads threads?    
  #:render renderer    
  #:periodic-renderer periodic-renderer])  void?
  thunk : (-> any/c)
  delay : nonnegative-number? = 0.05
  iterations : exact-nonnegative-integer? = 1
  threads? : any/c = #f
  renderer : (profile? . -> . any/c) = text:render
  periodic-renderer : (or/c #f (list/c nonnegative-number? (profile? . -> . any/c)))
   = #f

Executes the given thunk while collecting profiling data, and render this data when done. Keyword arguments can customize the profiling:

(profile expr keyword-arguments ...)

A macro version of profile-thunk. The keyword arguments can be specified in the same was as for a function call: they can appear before and/or after the expression to be profiled.

2 Collecting Profile Information

 (require profile/sampler)

(create-sampler to-track delay [super-cust])
  ((symbol?) (any/c) . ->* . any/c)
  to-track : 
(or/c thread? custodian?
      (listof (or/c thread? custodian?)))
  delay : nonnegative-number?
  super-cust : custodian? = (current-custodian)

Creates a sample collector thread, which tracks the given to-track value every delay seconds. The to-track value can be either a thread (track just that thread), a custodian (track all threads managed by the custodian), or a list of threads and/or custodians. If a custodian is given, it must be subordinate to super-cust, which defaults to the current custodian.

The resulting value is a controller function, which consumes a message consisting of a symbol and an optional argument, and can affect the sampler. The following messages are currently supported:

3 Analyzing Profile Data

 (require profile/analyzer)

Once a profile run is done, and the results are collected, the next step is to analyze the data. In this step the sample time are computed and summed, a call-graph representing the observed function calls is built, and per-node and per-edge information is created. This is the job of the main function provided by profile/analyzer.

(analyze-samples raw-sample-data)  profile?
  raw-sample-data : any/c

This function consumes the raw result of the sampler (which is given in an undocumented form), analyzes it, and returns a profile value holding the analyzed results. Without this function, the results of the sampler are meaningless.

(struct profile (total-time
    cpu-time
    sample-number
    thread-times
    nodes
    *-node))
  total-time : exact-nonnegative-integer?
  cpu-time : exact-nonnegative-integer?
  sample-number : exact-nonnegative-integer?
  thread-times : 
(listof (cons exact-nonnegative-integer?
              exact-nonnegative-integer?))
  nodes : (listof node?)
  *-node : node?

Represents the analyzed profile result.

(struct node (id src thread-ids total self callers callees))
  id : (or/c #f symbol?)
  src : (or/c #f srcloc?)
  thread-ids : (listof exact-nonnegative-integer?)
  total : exact-nonnegative-integer?
  self : exact-nonnegative-integer?
  callers : (listof edge?)
  callees : (listof edge?)

Represents a function call node in the call graph of an analyzed profile result.

(struct edge (total caller caller-time callee callee-time))
  total : exact-nonnegative-integer?
  caller : node?
  caller-time : exact-nonnegative-integer?
  callee : node?
  callee-time : exact-nonnegative-integer?

Represents an edge between two function call nodes in the call graph of an analyzed profile result.

4 Profile Renderers

After collecting the profile samples and analyzing the data, the last aspect of profiling is to render the results. The profile collection provides several renderers, each providing a rendering function that consumes a profile instance. See the analyzer section for a description of the profile struct if you want to implement your own renderer.

4.1 Textual Rendering

 (require profile/render-text)

(render profile-data    
  [#:truncate-source truncate-source    
  #:hide-self hide-self%    
  #:hide-subs hide-subs%])  void?
  profile-data : profile?
  truncate-source : exact-nonnegative-integer? = 50
  hide-self% : (between/c 0 1) = 1/100
  hide-subs% : (between/c 0 1) = 1/50

Prints the given profile results as a textual table.

The printout begins with some general facts about the profile, and then a table that represents the call-graph is printed. Each row in this table looks like:

                          B [M1] M2%
  [N1] N2(N3%) N4(N5%)  A ...path/to/source.ss:12:34
                          C [M3] M4%

Where actual numbers appear in the printout. The meaning of the numbers and labels is as follows:

The function has a few keyword arguments to customize its output:

4.2 Graph Rendering

 (require profile/render-graphviz)

(render profile-data    
  [#:hide-self hide-self%    
  #:hide-subs hide-subs%])  void?
  profile-data : profile?
  hide-self% : (between/c 0 1) = 1/100
  hide-subs% : (between/c 0 1) = 1/50

Prints the given profile results as a Graphviz directed graph.

This is an experimental module, provided mostly as a proof-of-concept. It renders the profile’s call-graph as a graph representation for one of the Graphviz tools to render. Nodes are colored according to their `self’ percentages, and edges.

The keyword arguments control hiding nodes in the same way as with the textual renderer.