/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/lsprof.py

  • Committer: Michael Ellerman
  • Date: 2006-03-09 00:24:48 UTC
  • mto: (1610.1.8 bzr.mbp.integration)
  • mto: This revision was merged to the branch mainline in revision 1616.
  • Revision ID: michael@ellerman.id.au-20060309002448-70cce15e3d605130
Make the "ignore line" in the commit message editor the "right" width, so
that if you make your message that wide it won't wrap in bzr log output.
Just as a visual aid.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# this is copied from the lsprof distro because somehow
 
2
# it is not installed by distutils
 
3
# I made one modification to profile so that it returns a pair
 
4
# instead of just the Stats object
 
5
 
 
6
import sys
 
7
from _lsprof import Profiler, profiler_entry, profiler_subentry
 
8
 
 
9
__all__ = ['profile', 'Stats']
 
10
 
 
11
def profile(f, *args, **kwds):
 
12
    """XXX docstring"""
 
13
    p = Profiler()
 
14
    p.enable(subcalls=True)
 
15
    try:
 
16
        ret = f(*args, **kwds)
 
17
    finally:
 
18
        p.disable()
 
19
    return ret,Stats(p.getstats())
 
20
 
 
21
 
 
22
class Stats(object):
 
23
    """XXX docstring"""
 
24
 
 
25
    def __init__(self, data):
 
26
        self.data = data
 
27
 
 
28
    def sort(self, crit="inlinetime"):
 
29
        """XXX docstring"""
 
30
        if crit not in profiler_entry.__dict__:
 
31
            raise ValueError, "Can't sort by %s" % crit
 
32
        self.data.sort(lambda b, a: cmp(getattr(a, crit),
 
33
                                        getattr(b, crit)))
 
34
        for e in self.data:
 
35
            if e.calls:
 
36
                e.calls.sort(lambda b, a: cmp(getattr(a, crit),
 
37
                                              getattr(b, crit)))
 
38
 
 
39
    def pprint(self, top=None, file=None):
 
40
        """XXX docstring"""
 
41
        if file is None:
 
42
            file = sys.stdout
 
43
        d = self.data
 
44
        if top is not None:
 
45
            d = d[:top]
 
46
        cols = "% 12s %12s %11.4f %11.4f   %s\n"
 
47
        hcols = "% 12s %12s %12s %12s %s\n"
 
48
        cols2 = "+%12s %12s %11.4f %11.4f +  %s\n"
 
49
        file.write(hcols % ("CallCount", "Recursive", "Total(ms)",
 
50
                            "Inline(ms)", "module:lineno(function)"))
 
51
        for e in d:
 
52
            file.write(cols % (e.callcount, e.reccallcount, e.totaltime,
 
53
                               e.inlinetime, label(e.code)))
 
54
            if e.calls:
 
55
                for se in e.calls:
 
56
                    file.write(cols % ("+%s" % se.callcount, se.reccallcount,
 
57
                                       se.totaltime, se.inlinetime,
 
58
                                       "+%s" % label(se.code)))
 
59
 
 
60
    def freeze(self):
 
61
        """Replace all references to code objects with string
 
62
        descriptions; this makes it possible to pickle the instance."""
 
63
 
 
64
        # this code is probably rather ickier than it needs to be!
 
65
        for i in range(len(self.data)):
 
66
            e = self.data[i]
 
67
            if not isinstance(e.code, str):
 
68
                self.data[i] = type(e)((label(e.code),) + e[1:])
 
69
                if e.calls:
 
70
                    for j in range(len(e.calls)):
 
71
                        se = e.calls[j]
 
72
                        if not isinstance(se.code, str):
 
73
                            e.calls[j] = type(se)((label(se.code),) + se[1:])
 
74
 
 
75
_fn2mod = {}
 
76
 
 
77
def label(code):
 
78
    if isinstance(code, str):
 
79
        return code
 
80
    try:
 
81
        mname = _fn2mod[code.co_filename]
 
82
    except KeyError:
 
83
        for k, v in sys.modules.iteritems():
 
84
            if v is None:
 
85
                continue
 
86
            if not hasattr(v, '__file__'):
 
87
                continue
 
88
            if not isinstance(v.__file__, str):
 
89
                continue
 
90
            if v.__file__.startswith(code.co_filename):
 
91
                mname = _fn2mod[code.co_filename] = k
 
92
                break
 
93
        else:
 
94
            mname = _fn2mod[code.co_filename] = '<%s>'%code.co_filename
 
95
    
 
96
    return '%s:%d(%s)' % (mname, code.co_firstlineno, code.co_name)
 
97
 
 
98
 
 
99
if __name__ == '__main__':
 
100
    import os
 
101
    sys.argv = sys.argv[1:]
 
102
    if not sys.argv:
 
103
        print >> sys.stderr, "usage: lsprof.py <script> <arguments...>"
 
104
        sys.exit(2)
 
105
    sys.path.insert(0, os.path.abspath(os.path.dirname(sys.argv[0])))
 
106
    stats = profile(execfile, sys.argv[0], globals(), locals())
 
107
    stats.sort()
 
108
    stats.pprint()