~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/lsprof.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-07-06 03:15:29 UTC
  • mfrom: (1711.2.78 jam-integration)
  • Revision ID: pqm@pqm.ubuntu.com-20060706031529-e189d8c3f42076be
(jam) allow plugins to include benchmarks

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
# I made one modification to profile so that it returns a pair
4
4
# instead of just the Stats object
5
5
 
6
 
import cPickle
7
 
import os
8
6
import sys
9
7
import thread
10
8
import threading
106
104
        """Output profiling data in calltree format (for KCacheGrind)."""
107
105
        _CallTreeFilter(self.data).output(file)
108
106
 
109
 
    def save(self, filename, format=None):
110
 
        """Save profiling data to a file.
111
 
 
112
 
        :param filename: the name of the output file
113
 
        :param format: 'txt' for a text representation;
114
 
            'callgrind' for calltree format;
115
 
            otherwise a pickled Python object. A format of None indicates
116
 
            that the format to use is to be found from the extension of
117
 
            filename.
118
 
        """
119
 
        if format is None:
120
 
            ext = os.path.splitext(filename)[1]
121
 
            if len(ext) > 1:
122
 
                format = ext[1:]
123
 
        outfile = open(filename, 'wb')
124
 
        try:
125
 
            if format == "callgrind":
126
 
                self.calltree(outfile)
127
 
            elif format == "txt":
128
 
                self.pprint(file=outfile)
129
 
            else:
130
 
                self.freeze()
131
 
                cPickle.dump(self, outfile, 2)
132
 
        finally:
133
 
            outfile.close()
134
 
 
135
107
 
136
108
class _CallTreeFilter(object):
137
 
    """Converter of a Stats object to input suitable for KCacheGrind.
138
 
 
139
 
    This code is taken from http://ddaa.net/blog/python/lsprof-calltree
140
 
    with the changes made by J.P. Calderone and Itamar applied. Note that
141
 
    isinstance(code, str) needs to be used at times to determine if the code 
142
 
    object is actually an external code object (with a filename, etc.) or
143
 
    a Python built-in.
144
 
    """
145
109
 
146
110
    def __init__(self, data):
147
111
        self.data = data
166
130
        code = entry.code
167
131
        inlinetime = int(entry.inlinetime * 1000)
168
132
        #print >> out_file, 'ob=%s' % (code.co_filename,)
169
 
        if isinstance(code, str):
170
 
            print >> out_file, 'fi=~'
171
 
        else:
172
 
            print >> out_file, 'fi=%s' % (code.co_filename,)
 
133
        print >> out_file, 'fi=%s' % (code.co_filename,)
173
134
        print >> out_file, 'fn=%s' % (label(code, True),)
174
 
        if isinstance(code, str):
175
 
            print >> out_file, '0 ', inlinetime
176
 
        else:
177
 
            print >> out_file, '%d %d' % (code.co_firstlineno, inlinetime)
 
135
        print >> out_file, '%d %d' % (code.co_firstlineno, inlinetime)
178
136
        # recursive calls are counted in entry.calls
179
137
        if entry.calls:
180
138
            calls = entry.calls
181
139
        else:
182
140
            calls = []
183
 
        if isinstance(code, str):
184
 
            lineno = 0
185
 
        else:
186
 
            lineno = code.co_firstlineno
187
141
        for subentry in calls:
188
 
            self._subentry(lineno, subentry)
 
142
            self._subentry(code.co_firstlineno, subentry)
189
143
        print >> out_file
190
144
 
191
145
    def _subentry(self, lineno, subentry):
194
148
        totaltime = int(subentry.totaltime * 1000)
195
149
        #print >> out_file, 'cob=%s' % (code.co_filename,)
196
150
        print >> out_file, 'cfn=%s' % (label(code, True),)
197
 
        if isinstance(code, str):
198
 
            print >> out_file, 'cfi=~'
199
 
            print >> out_file, 'calls=%d 0' % (subentry.callcount,)
200
 
        else:
201
 
            print >> out_file, 'cfi=%s' % (code.co_filename,)
202
 
            print >> out_file, 'calls=%d %d' % (
203
 
                subentry.callcount, code.co_firstlineno)
 
151
        print >> out_file, 'cfi=%s' % (code.co_filename,)
 
152
        print >> out_file, 'calls=%d %d' % (
 
153
            subentry.callcount, code.co_firstlineno)
204
154
        print >> out_file, '%d %d' % (lineno, totaltime)
205
155
 
 
156
 
206
157
_fn2mod = {}
207
158
 
208
159
def label(code, calltree=False):
211
162
    try:
212
163
        mname = _fn2mod[code.co_filename]
213
164
    except KeyError:
214
 
        for k, v in sys.modules.items():
 
165
        for k, v in sys.modules.iteritems():
215
166
            if v is None:
216
167
                continue
217
 
            if getattr(v, '__file__', None) is None:
 
168
            if not hasattr(v, '__file__'):
218
169
                continue
219
170
            if not isinstance(v.__file__, str):
220
171
                continue