python-2.5.2/win32/Lib/cProfile.py
changeset 0 ae805ac0140d
equal deleted inserted replaced
-1:000000000000 0:ae805ac0140d
       
     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()