racket/collects/profile/scribblings/renderers.scrbl
Eli Barzilay c0a8a01222 Changed @itemize{...} to @itemize[...] (done after comparing the doc
tree and verifying that there are no changes).
(Also fixed a few bugs that were in the code)

svn: r14427
2009-04-05 17:46:20 +00:00

130 lines
5.4 KiB
Racket

#lang scribble/doc
@(require scribble/manual
(for-label scheme
profile/analyzer
(prefix-in text: profile/render-text)
(prefix-in graphviz: profile/render-graphviz)))
@title[#:tag "renderers"]{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 @scheme[profile] instance. See the
@seclink["analyzer"]{analyzer} section for a description of the
@scheme[profile] struct if you want to implement your own renderer.
@;--------------------------------------------------------------------
@section{Textual Rendering}
@defmodule[profile/render-text]
@defproc[(render
[profile-data profile?]
[#:truncate-source truncate-source exact-nonnegative-integer? 50]
[#:hide-self hide-self% (between/c 0 1) 1/100]
[#:hide-subs hide-subs% (between/c 0 1) 2/100])
void?]{
Prints the given @scheme[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:
@verbatim[#:indent 2]{
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:
@itemize[
@item{@tt{A} --- the name of the function that this node represents,
followed by the source location for the function if it is known.
The name can be ``???'' for functions with no identifier, but in
this case the source location will identify them.}
@item{@tt{N1} --- an index number associated with this node. This is
important in references to this function, since the symbolic names
are not unique (and some can be missing). The number itself has no
significance, it simply goes from 1 up.}
@item{@tt{N2} --- the time (in milliseconds) that this function has
been anywhere in a stack snapshot. This is the total time that the
execution was somewhere in this function or in its callees.
(Corresponds to the @scheme[node-total] field.)}
@item{@tt{N3} --- this is the percentage of the node's total time
(@tt{N2}) from the total observed time of the profile. An entry
with a 100% refers to a function that was active throughout the
whole execution.}
@item{@tt{N4} --- the time (in milliseconds) that this function has
been at the top of the stack snapshot. This is the time that this
function consumed doing work itself rather than calling other
functions. (Corresponds to the @scheme[node-self] field.)}
@item{@tt{N5} --- this is the percentage of @tt{N4} out of the total
observed time of the profile. Functions with high values here can
be good candidates for optimization, But, of course, they can
represent doing real work due to one of its callers that need to be
optimized.}
@item{@tt{B} and @tt{C} --- these are labels for the callers and
callees of the function. Any number of callers and callees can
appear here (including 0). The function itself can also appear in
both places if it is (non-tail) recursive.}
@item{@tt{M1} and @tt{M3} --- the index numbers for @tt{B} and
@tt{C}. They can be used to disambiguate functions with the same
name, as well as a quick way to find the corresponding entry in the
table.}
@item{@tt{M2} and @tt{M4} --- the percentages of the time @tt{A} spent
being called by @tt{B} and calling @tt{C}. These percentages
represent the time that this edge was found on a stack snapshot,
divided by the number of occurrences of @tt{A} on the same snapshot.
The number is the percentage of these times out of @tt{N2}, the
total time @tt{A} has been active.
The total percentages for the all caller and for all callees should
be close to 100% minus the time @tt{A} was the leaf or the root.
These values correspond to the @scheme[edge-caller-time] and
@scheme[edge-callee-time] fields; see the documentation for further
details.}
]
The function has a few keyword arguments to customize its output:
@itemize[
@item{The @scheme[truncate-source] argument determines the length that
the source string should take (together with its label).}
@item{@scheme[hide-self%] and @scheme[hide-subs%] control hiding some
of the nodes. A node is hidden if its self time (@tt{N3} in the
above example) is smaller than @scheme[hide-self%] @emph{and} if all
places where it occurs as a caller or a callee have percentages that
are smaller than @scheme[hide-subs%]. The reason for requiring both
conditions is to avoid having ``dangling references'' to hidden
nodes.}
]}
@;--------------------------------------------------------------------
@section{Graph Rendering}
@defmodule[profile/render-graphviz]
@defproc[(render
[profile-data profile?]
[#:hide-self hide-self% (between/c 0 1) 1/100]
[#:hide-subs hide-subs% (between/c 0 1) 2/100])
void?]{
Prints the given @scheme[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.}