is rudimentary, but it shows exactly
where your slow task has spent your user’s 2,468 seconds. With the data shown
here, for example, you can derive the
percentage of response time contribution for each of the function calls identified in the profile. You can also derive
the average response time for each type
of function call during your task.
A profile shows where your code has
spent your time and—sometimes even
more importantly—where it has not.
There is tremendous value in not having to guess about these things.
From the data shown in Table
3, you know that 70.8% of your user’s response time is consumed by
DB:fetch() calls. Furthermore, if
you can drill down in to the individual
calls whose durations were aggregated to create this profile, you can know
how many of those App:await _
db _ netIO() calls corresponded to
DB:fetch() calls, and you can know
how much response time each of
those consumed. With a profile, you
can begin to formulate the answer to
the question, “How long should this
task run?”… which, by now, you know
is an important question in the first
step (section 0) of any good problem
diagnosis.
Table 4. It’s the same profile as in Table
3, except here you can see how much
time you think you can save by implementing the best remedy for each row in
the profile, and you can see how much
you think each remedy will cost to implement.
Which remedy action would you implement first? Amdahl’s Law says that
implementing the repair on line 1 has
the greatest potential benefit of saving
about 851 seconds ( 34.5% of 2,468 seconds). If it is truly “super expensive,”
however, then the remedy on line 2 may
yield better a net benefit—and that is
the constraint to which you really need
to optimize—even though the potential
for response time savings is only about
305 seconds.
A tremendous value of the profile is
that you can learn exactly how much
improvement you should expect for
a proposed investment. It opens the
door to making much better deci-
sions about what remedies to imple-
ment first. Your predictions give you
a yardstick for measuring your own
performance as an analyst. Finally, it
gives you a chance to showcase your
cleverness and intimacy with your
technology as you find more efficient
remedies for reducing response time
more than expected, at lower-than-
expected costs.
table 3. this profile shows the decomposition of a 2,468.000-second response time.
amdahl’s Law
Profiling helps you think clearly about
performance. Even if Gene Amdahl
had not given us Amdahl’s Law back
in 1967, you would probably have
come up with it yourself after the first
few profiles you looked at.
Amdahl’s Law states: Performance
improvement is proportional to how
much a program uses the thing you
improved. If the thing you’re trying
to improve contributes only 5% to
your task’s total response time, then
the maximum impact you’ll be able
to make is 5% of your total response
time. This means that the closer to
the top of a profile that you work (
assuming that the profile is sorted in
descending response-time order), the
bigger the benefit potential for your
overall response time.
This doesn’t mean that you always
work a profile in top-down order,
though, because you also need to consider the cost of the remedies you’ll be
executing. 3
Example 5. Consider the profile in
function Call
1 DB: fetch()
2 App: await _ db _ netIO()
3 DB: execute()
4 DB: prepare()
5 other
6 App: render _ graph()
7 App: tabularize()
8 App: read()
total
R (sec)
1,748.229
338.470
152.654
97.855
58.147
48.274
23.481
0.890
2,468.000
Calls
322,968
322,968
39,142
39,142
89,422
7
4
2
table 4. this profile shows the potential for improvement and the corresponding cost
(difficulty) of improvement for each line item from table 2.
Potential improvement and cost of investment
1 34.5% super expensive
2 12.3% dirt cheap
3 Impossible to improve
4 4.0% dirt cheap
5 0.1% super expensive
6 1.6% dirt cheap
7 Impossible to improve
8 0.0% dirt cheap
total
R (sec)
1,748.229
338.470
152.654
97.855
58.147
48.274
23.481
0.890
2,468.000
R (%)
70.8%
13.7%
6.2%
4.0%
2.4%
2.0%
1.0%
0.0%