Profiling

As a general rule, 90% of the execution time of your program
will be spent in 10% of its code. Profilers are tools that help you
identify the 10% of hot spots that constrain the speed of your
program. This is a good thing for making it faster.

But in the Unix tradition, profilers have a far more important
function. They enable you not to optimize the other 90%!
This is good, and not just because it saves you work. The
really valuable effect is that not optimizing that 90%
holds down global complexity and reduces bugs.

You may recall that we quoted Donald
Knuth
observing “Premature optimization is the root of all
evil”
in Chapter 1, and that
Rob Pike and Ken
Thompson had a
few pungent observations on the topic as well. These were the voices
of experience. Do good design. Think about what's
right first. Tune for efficiency later.

Profilers help you do this. If you get in the good habit of
using them, you can get rid of the bad habit of premature
optimization. Profilers don't just change the way you work; they
change how you think.

Profilers for compiled languages rely on instrumenting object
code, so they are even more platform-dependent than compilers. On the
other hand, a compiled-language profiler doesn't care about the source
language of the programs it instruments. Under Unix, the single
profiler
gprof(1)
handles C,
C++, and all
other compiled languages.

Perl,
Python, and
Emacs Lisp have their own profilers included in
their basic distributions; these are portable across all platforms on
which the host languages themselves run. Java has built-in profiling.
Tcl has no
profiling support as yet.