]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/python/contrib/Lib/cProfile.py
Inital import
[l4.git] / l4 / pkg / python / contrib / Lib / cProfile.py
1 #! /usr/bin/env python
2
3 """Python interface for the 'lsprof' profiler.
4    Compatible with the 'profile' module.
5 """
6
7 __all__ = ["run", "runctx", "help", "Profile"]
8
9 import _lsprof
10
11 # ____________________________________________________________
12 # Simple interface
13
14 def run(statement, filename=None, sort=-1):
15     """Run statement under profiler optionally saving results in filename
16
17     This function takes a single argument that can be passed to the
18     "exec" statement, and an optional file name.  In all cases this
19     routine attempts to "exec" its first argument and gather profiling
20     statistics from the execution. If no file name is present, then this
21     function automatically prints a simple profiling report, sorted by the
22     standard name string (file/line/function-name) that is presented in
23     each line.
24     """
25     prof = Profile()
26     result = None
27     try:
28         try:
29             prof = prof.run(statement)
30         except SystemExit:
31             pass
32     finally:
33         if filename is not None:
34             prof.dump_stats(filename)
35         else:
36             result = prof.print_stats(sort)
37     return result
38
39 def runctx(statement, globals, locals, filename=None):
40     """Run statement under profiler, supplying your own globals and locals,
41     optionally saving results in filename.
42
43     statement and filename have the same semantics as profile.run
44     """
45     prof = Profile()
46     result = None
47     try:
48         try:
49             prof = prof.runctx(statement, globals, locals)
50         except SystemExit:
51             pass
52     finally:
53         if filename is not None:
54             prof.dump_stats(filename)
55         else:
56             result = prof.print_stats()
57     return result
58
59 # Backwards compatibility.
60 def help():
61     print "Documentation for the profile/cProfile modules can be found "
62     print "in the Python Library Reference, section 'The Python Profiler'."
63
64 # ____________________________________________________________
65
66 class Profile(_lsprof.Profiler):
67     """Profile(custom_timer=None, time_unit=None, subcalls=True, builtins=True)
68
69     Builds a profiler object using the specified timer function.
70     The default timer is a fast built-in one based on real time.
71     For custom timer functions returning integers, time_unit can
72     be a float specifying a scale (i.e. how long each integer unit
73     is, in seconds).
74     """
75
76     # Most of the functionality is in the base class.
77     # This subclass only adds convenient and backward-compatible methods.
78
79     def print_stats(self, sort=-1):
80         import pstats
81         pstats.Stats(self).strip_dirs().sort_stats(sort).print_stats()
82
83     def dump_stats(self, file):
84         import marshal
85         f = open(file, 'wb')
86         self.create_stats()
87         marshal.dump(self.stats, f)
88         f.close()
89
90     def create_stats(self):
91         self.disable()
92         self.snapshot_stats()
93
94     def snapshot_stats(self):
95         entries = self.getstats()
96         self.stats = {}
97         callersdicts = {}
98         # call information
99         for entry in entries:
100             func = label(entry.code)
101             nc = entry.callcount         # ncalls column of pstats (before '/')
102             cc = nc - entry.reccallcount # ncalls column of pstats (after '/')
103             tt = entry.inlinetime        # tottime column of pstats
104             ct = entry.totaltime         # cumtime column of pstats
105             callers = {}
106             callersdicts[id(entry.code)] = callers
107             self.stats[func] = cc, nc, tt, ct, callers
108         # subcall information
109         for entry in entries:
110             if entry.calls:
111                 func = label(entry.code)
112                 for subentry in entry.calls:
113                     try:
114                         callers = callersdicts[id(subentry.code)]
115                     except KeyError:
116                         continue
117                     nc = subentry.callcount
118                     cc = nc - subentry.reccallcount
119                     tt = subentry.inlinetime
120                     ct = subentry.totaltime
121                     if func in callers:
122                         prev = callers[func]
123                         nc += prev[0]
124                         cc += prev[1]
125                         tt += prev[2]
126                         ct += prev[3]
127                     callers[func] = nc, cc, tt, ct
128
129     # The following two methods can be called by clients to use
130     # a profiler to profile a statement, given as a string.
131
132     def run(self, cmd):
133         import __main__
134         dict = __main__.__dict__
135         return self.runctx(cmd, dict, dict)
136
137     def runctx(self, cmd, globals, locals):
138         self.enable()
139         try:
140             exec cmd in globals, locals
141         finally:
142             self.disable()
143         return self
144
145     # This method is more useful to profile a single function call.
146     def runcall(self, func, *args, **kw):
147         self.enable()
148         try:
149             return func(*args, **kw)
150         finally:
151             self.disable()
152
153 # ____________________________________________________________
154
155 def label(code):
156     if isinstance(code, str):
157         return ('~', 0, code)    # built-in functions ('~' sorts at the end)
158     else:
159         return (code.co_filename, code.co_firstlineno, code.co_name)
160
161 # ____________________________________________________________
162
163 def main():
164     import os, sys
165     from optparse import OptionParser
166     usage = "cProfile.py [-o output_file_path] [-s sort] scriptfile [arg] ..."
167     parser = OptionParser(usage=usage)
168     parser.allow_interspersed_args = False
169     parser.add_option('-o', '--outfile', dest="outfile",
170         help="Save stats to <outfile>", default=None)
171     parser.add_option('-s', '--sort', dest="sort",
172         help="Sort order when printing to stdout, based on pstats.Stats class", default=-1)
173
174     if not sys.argv[1:]:
175         parser.print_usage()
176         sys.exit(2)
177
178     (options, args) = parser.parse_args()
179     sys.argv[:] = args
180
181     if (len(sys.argv) > 0):
182         sys.path.insert(0, os.path.dirname(sys.argv[0]))
183         run('execfile(%r)' % (sys.argv[0],), options.outfile, options.sort)
184     else:
185         parser.print_usage()
186     return parser
187
188 # When invoked as main program, invoke the profiler on a script
189 if __name__ == '__main__':
190     main()