August 09, 2001
Creating Perl Code Graphsbrian d foy
The open-source
Devel::GraphVizProf module is a graphing tool that can help developers visualize structural information, such as code flow, database table relationships, and more.
In my last article I showed you how to profile your code using the
A graph, in this sense, is a collection of connected nodes. The nodes in code
graphs are the executable statements of the program and are connected by "edges"
which show the flow of code from one statement to the next. This sort of graph
is also known as a "directed graph," since the edges show the direction of flow
from node to node.
GraphViz is an open-source
graphing program developed by AT&T that can help developers visualize structural
information, such as code flow, database table relationships,
or the links between web pages. GraphViz and many
other interesting tools are provided free of charge by AT&T. The ease of
installation of this package can depend on your operating system. On FreeBSD simply go to
You can get Devel::GraphVizProf
from the Comprehensive Perl
Archive Network. It is in the GraphViz
module distribution by Leon Brocard, who also presented a talk
about Perl code graphs at YAPC::Europe 2000. It does not install
automatically as of version 0.12 but all that you
need to do is copy the
GraphViz
can do quite a bit and comes with more tools than I will show,
but you can see the documentation
for more details. To show a simple code graph, I wrote this sample program,
dot utility that comes with the GraphViz
distribution. This program can produce output in several
formats including Adobe PostScript, FrameMaker MIF, PNG, and many
others. For this article I will use PNG so you can see
the images. To generate the image file, I tell
dot which output format I want with the
-T switch and what the output file name is with
the -o switch along with the name of the file
that has the graph description. The -G switch allows me to
specify options for the entire graph. In this case I want the
color of the background to be white. You might not need this, but
if you get an image full of black, that probably means GraphViz does
not know which color you want to use for the background and uses
black by default.
I can also change the color of the edges so that I can encode
more information in the graph. The color of the edge can be used
to indicate how often the program goes from one statement to another.
I can then literally see the parts of the program that might deserve
more consideration for optimization or debugging. In this example,
I have colored the lines involved in the loop blue to indicate that
they execute more often than the other lines.
I already know that the Devel::SmallProf
module can count the number of times the a line of code is
executed and how much time it takes to execute that line. The
Devel::GraphVizProf
module does the same thing. Rather than output a text report
like Devel::SmallProf
does, Devel::GraphVizProf
outputs a graph description. It uses the edge color to encode
the line counts. Statements that are connected infrequently
relative to other statements are colored darker and statements
that are connected more frequently are colored more brightly.
In this example, the edges that are black only happen a couple
of times while the ones colored blue happen very frequently. I
can easily identify where my program is spending time by
looking at the colored lines rather than going through lines of
test input. The power of pictures becomes apparent.
I modified the example script to add some lines of code that will be executed more
often than those in the while loop to show how Devel::GraphVizProf
displays relative frequencies of execution.
Devel::GraphVizProf
debugger by using the -d switch.
dot to create the graph. I can
send the output to dot directly, but often the program I graph
sends other information to standard output or I want to change the node information
a bit. I save the information in a file until I am ready to make the graph.
.smallprof file in the same directory from which I will
run the program. The .smallprof file is included in the Devel::GraphVizProf
module at runtime with do {}, so I can put valid Perl statements
in there. If I create a hash named %DB::packages, Devel::GraphVizProf
only profiles packages that exist as keys in that hash and have a true value
(which is anything that is not 0, the empty string, or undef),
and these are the only packages that will appear in the code graph.
By default, Perl programs are in the main
namespace (or package) which corresponds to the main() loop in C. If I want
to profile and graph only statements in the main namespace, I can use this
.smallprof file.
The new image is much smaller and only shows the code of interest. Notice
that the lines that execute more often are connected by lines that are brighter
colors. If I had a much longer program, and a much larger code graph, I could
easily scan the image looking for the brightest colored lines to see where the
program is spending its time. Although this is not going to unlock the secrets
of my program, I can use the graph along with other information to decide how
to optimize or debug it.
Just for kicks, I ran the test.pl script
from the Business::ISBN
module under the Devel::GraphVizProf
debugger using a different .smallprof file
so that I could also profile code in the Business::ISBN namespace.
The code graph generates a rather large image of the program: isbn.gif (312 KB and 7866x6068).
There is a lot more that you can do with GraphViz to make these graphs prettier, but that is up to you. You can install more fonts, use different colors or outlines, and many other things to justify the use of a really expensive printer. Just do not tell your friends and co-workers how easy it is to do. :)
brian d foy has been a Perl user since 1994. He is founder of the first Perl users group, NY.pm, and Perl Mongers, the Perl advocacy organization. He has been teaching Perl through Stonehenge Consulting for the past three years, and has been a featured speaker at The Perl Conference, Perl University, YAPC, COMDEX, and Builder.com. Some of brian's other articles have appeared in The Perl Journal.
|
|
||||||||||||||||||||||||||||
|
|
|
|