~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/lsprof.py

  • Committer: Ian Clatworthy
  • Date: 2009-09-09 11:43:10 UTC
  • mto: (4634.37.2 prepare-2.0)
  • mto: This revision was merged to the branch mainline in revision 4689.
  • Revision ID: ian.clatworthy@canonical.com-20090909114310-glw7tv76i5gnx9pt
put rules back in Makefile supporting plain-style docs

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
import threading
11
11
from _lsprof import Profiler, profiler_entry
12
12
 
 
13
 
13
14
__all__ = ['profile', 'Stats']
14
15
 
15
16
_g_threadmap = {}
26
27
 
27
28
 
28
29
def profile(f, *args, **kwds):
29
 
    """XXX docstring"""
 
30
    """Run a function profile.
 
31
 
 
32
    Exceptions are not caught: If you need stats even when exceptions are to be
 
33
    raised, passing in a closure that will catch the exceptions and transform
 
34
    them appropriately for your driver function.
 
35
 
 
36
    :return: The functions return value and a stats object.
 
37
    """
30
38
    global _g_threadmap
31
39
    p = Profiler()
32
40
    p.enable(subcalls=True)
38
46
        for pp in _g_threadmap.values():
39
47
            pp.disable()
40
48
        threading.setprofile(None)
41
 
    
 
49
 
42
50
    threads = {}
43
51
    for tid, pp in _g_threadmap.items():
44
52
        threads[tid] = Stats(pp.getstats(), {})
118
126
            otherwise the format is given by the filename extension.
119
127
        """
120
128
        if format is None:
121
 
            if filename.startswith('callgrind.out'):
 
129
            basename = os.path.basename(filename)
 
130
            if basename.startswith('callgrind.out'):
122
131
                format = "callgrind"
123
132
            else:
124
133
                ext = os.path.splitext(filename)[1]
142
151
 
143
152
    This code is taken from http://ddaa.net/blog/python/lsprof-calltree
144
153
    with the changes made by J.P. Calderone and Itamar applied. Note that
145
 
    isinstance(code, str) needs to be used at times to determine if the code 
 
154
    isinstance(code, str) needs to be used at times to determine if the code
146
155
    object is actually an external code object (with a filename, etc.) or
147
156
    a Python built-in.
148
157
    """
152
161
        self.out_file = None
153
162
 
154
163
    def output(self, out_file):
155
 
        self.out_file = out_file        
156
 
        print >> out_file, 'events: Ticks'
 
164
        self.out_file = out_file
 
165
        out_file.write('events: Ticks\n')
157
166
        self._print_summary()
158
167
        for entry in self.data:
159
168
            self._entry(entry)
163
172
        for entry in self.data:
164
173
            totaltime = int(entry.totaltime * 1000)
165
174
            max_cost = max(max_cost, totaltime)
166
 
        print >> self.out_file, 'summary: %d' % (max_cost,)
 
175
        self.out_file.write('summary: %d\n' % (max_cost,))
167
176
 
168
177
    def _entry(self, entry):
169
178
        out_file = self.out_file
170
179
        code = entry.code
171
180
        inlinetime = int(entry.inlinetime * 1000)
172
 
        #print >> out_file, 'ob=%s' % (code.co_filename,)
173
 
        if isinstance(code, str):
174
 
            print >> out_file, 'fi=~'
175
 
        else:
176
 
            print >> out_file, 'fi=%s' % (code.co_filename,)
177
 
        print >> out_file, 'fn=%s' % (label(code, True),)
178
 
        if isinstance(code, str):
179
 
            print >> out_file, '0 ', inlinetime
180
 
        else:
181
 
            print >> out_file, '%d %d' % (code.co_firstlineno, inlinetime)
 
181
        #out_file.write('ob=%s\n' % (code.co_filename,))
 
182
        if isinstance(code, str):
 
183
            out_file.write('fi=~\n')
 
184
        else:
 
185
            out_file.write('fi=%s\n' % (code.co_filename,))
 
186
        out_file.write('fn=%s\n' % (label(code, True),))
 
187
        if isinstance(code, str):
 
188
            out_file.write('0  %s\n' % (inlinetime,))
 
189
        else:
 
190
            out_file.write('%d %d\n' % (code.co_firstlineno, inlinetime))
182
191
        # recursive calls are counted in entry.calls
183
192
        if entry.calls:
184
193
            calls = entry.calls
190
199
            lineno = code.co_firstlineno
191
200
        for subentry in calls:
192
201
            self._subentry(lineno, subentry)
193
 
        print >> out_file
 
202
        out_file.write('\n')
194
203
 
195
204
    def _subentry(self, lineno, subentry):
196
205
        out_file = self.out_file
197
206
        code = subentry.code
198
207
        totaltime = int(subentry.totaltime * 1000)
199
 
        #print >> out_file, 'cob=%s' % (code.co_filename,)
200
 
        print >> out_file, 'cfn=%s' % (label(code, True),)
 
208
        #out_file.write('cob=%s\n' % (code.co_filename,))
 
209
        out_file.write('cfn=%s\n' % (label(code, True),))
201
210
        if isinstance(code, str):
202
 
            print >> out_file, 'cfi=~'
203
 
            print >> out_file, 'calls=%d 0' % (subentry.callcount,)
 
211
            out_file.write('cfi=~\n')
 
212
            out_file.write('calls=%d 0\n' % (subentry.callcount,))
204
213
        else:
205
 
            print >> out_file, 'cfi=%s' % (code.co_filename,)
206
 
            print >> out_file, 'calls=%d %d' % (
207
 
                subentry.callcount, code.co_firstlineno)
208
 
        print >> out_file, '%d %d' % (lineno, totaltime)
 
214
            out_file.write('cfi=%s\n' % (code.co_filename,))
 
215
            out_file.write('calls=%d %d\n' % (
 
216
                subentry.callcount, code.co_firstlineno))
 
217
        out_file.write('%d %d\n' % (lineno, totaltime))
209
218
 
210
219
_fn2mod = {}
211
220
 
237
246
    import os
238
247
    sys.argv = sys.argv[1:]
239
248
    if not sys.argv:
240
 
        print >> sys.stderr, "usage: lsprof.py <script> <arguments...>"
 
249
        sys.stderr.write("usage: lsprof.py <script> <arguments...>\n")
241
250
        sys.exit(2)
242
251
    sys.path.insert(0, os.path.abspath(os.path.dirname(sys.argv[0])))
243
252
    stats = profile(execfile, sys.argv[0], globals(), locals())