diff options
author | Armin Rigo <arigo@tunes.org> | 2006-02-08 12:53:56 (GMT) |
---|---|---|
committer | Armin Rigo <arigo@tunes.org> | 2006-02-08 12:53:56 (GMT) |
commit | a871ef2b3e924f058ec1b0aed7d4c83a546414b7 (patch) | |
tree | 0f214529cc5f93d06b28e56569d36c1d1ee80996 /Lib/pstats.py | |
parent | 5eefdca65477bd8d3a408c380323d4af3228a667 (diff) | |
download | cpython-a871ef2b3e924f058ec1b0aed7d4c83a546414b7.zip cpython-a871ef2b3e924f058ec1b0aed7d4c83a546414b7.tar.gz cpython-a871ef2b3e924f058ec1b0aed7d4c83a546414b7.tar.bz2 |
Added the cProfile module.
Based on lsprof (patch #1212837) by Brett Rosen and Ted Czotter.
With further editing by Michael Hudson and myself.
History in svn repo: http://codespeak.net/svn/user/arigo/hack/misc/lsprof
* Module/_lsprof.c is the internal C module, Lib/cProfile.py a wrapper.
* pstats.py updated to display cProfile's caller/callee timings if available.
* setup.py and NEWS updated.
* documentation updates in the profiler section:
- explain the differences between the three profilers that we have now
- profile and cProfile can use a unified documentation, like (c)Pickle
- mention that hotshot is "for specialized usage" now
- removed references to the "old profiler" that no longer exists
* test updates:
- extended test_profile to cover delicate cases like recursion
- added tests for the caller/callee displays
- added test_cProfile, performing the same tests for cProfile
* TO-DO:
- cProfile gives a nicer name to built-in, particularly built-in methods,
which could be backported to profile.
- not tested on Windows recently!
Diffstat (limited to 'Lib/pstats.py')
-rw-r--r-- | Lib/pstats.py | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/Lib/pstats.py b/Lib/pstats.py index 98f351f..930cc6d 100644 --- a/Lib/pstats.py +++ b/Lib/pstats.py @@ -371,27 +371,47 @@ class Stats: self.print_call_heading(width, "was called by...") for func in list: cc, nc, tt, ct, callers = self.stats[func] - self.print_call_line(width, func, callers) + self.print_call_line(width, func, callers, "<-") print print return self def print_call_heading(self, name_size, column_title): print "Function ".ljust(name_size) + column_title - - def print_call_line(self, name_size, source, call_dict): - print func_std_string(source).ljust(name_size), + # print sub-header only if we have new-style callers + subheader = False + for cc, nc, tt, ct, callers in self.stats.itervalues(): + if callers: + value = callers.itervalues().next() + subheader = isinstance(value, tuple) + break + if subheader: + print " "*name_size + " ncalls tottime cumtime" + + def print_call_line(self, name_size, source, call_dict, arrow="->"): + print func_std_string(source).ljust(name_size) + arrow, if not call_dict: - print "--" + print return clist = call_dict.keys() clist.sort() - name_size = name_size + 1 indent = "" for func in clist: name = func_std_string(func) - print indent*name_size + name + '(%r)' % (call_dict[func],), \ - f8(self.stats[func][3]) + value = call_dict[func] + if isinstance(value, tuple): + nc, cc, tt, ct = value + if nc != cc: + substats = '%d/%d' % (nc, cc) + else: + substats = '%d' % (nc,) + substats = '%s %s %s %s' % (substats.rjust(7+2*len(indent)), + f8(tt), f8(ct), name) + left_width = name_size + 1 + else: + substats = '%s(%r) %s' % (name, value, f8(self.stats[func][3])) + left_width = name_size + 3 + print indent*left_width + substats indent = " " def print_title(self): @@ -448,7 +468,15 @@ def func_get_function_name(func): return func[2] def func_std_string(func_name): # match what old profile produced - return "%s:%d(%s)" % func_name + if func_name[:2] == ('~', 0): + # special case for built-in functions + name = func_name[2] + if name.startswith('<') and name.endswith('>'): + return '{%s}' % name[1:-1] + else: + return name + else: + return "%s:%d(%s)" % func_name #************************************************************************** # The following functions combine statists for pairs functions. |