104
106
"""Output profiling data in calltree format (for KCacheGrind)."""
105
107
_CallTreeFilter(self.data).output(file)
109
def save(self, filename, format=None):
110
"""Save profiling data to a file.
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
120
ext = os.path.splitext(filename)[1]
123
outfile = open(filename, 'wb')
125
if format == "callgrind":
126
self.calltree(outfile)
127
elif format == "txt":
128
self.pprint(file=outfile)
131
cPickle.dump(self, outfile, 2)
108
136
class _CallTreeFilter(object):
137
"""Converter of a Stats object to input suitable for KCacheGrind.
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
110
146
def __init__(self, data):
130
166
code = entry.code
131
167
inlinetime = int(entry.inlinetime * 1000)
132
168
#print >> out_file, 'ob=%s' % (code.co_filename,)
133
print >> out_file, 'fi=%s' % (code.co_filename,)
169
if isinstance(code, str):
170
print >> out_file, 'fi=~'
172
print >> out_file, 'fi=%s' % (code.co_filename,)
134
173
print >> out_file, 'fn=%s' % (label(code, True),)
135
print >> out_file, '%d %d' % (code.co_firstlineno, inlinetime)
174
if isinstance(code, str):
175
print >> out_file, '0 ', inlinetime
177
print >> out_file, '%d %d' % (code.co_firstlineno, inlinetime)
136
178
# recursive calls are counted in entry.calls
138
180
calls = entry.calls
183
if isinstance(code, str):
186
lineno = code.co_firstlineno
141
187
for subentry in calls:
142
self._subentry(code.co_firstlineno, subentry)
188
self._subentry(lineno, subentry)
143
189
print >> out_file
145
191
def _subentry(self, lineno, subentry):
148
194
totaltime = int(subentry.totaltime * 1000)
149
195
#print >> out_file, 'cob=%s' % (code.co_filename,)
150
196
print >> out_file, 'cfn=%s' % (label(code, True),)
151
print >> out_file, 'cfi=%s' % (code.co_filename,)
152
print >> out_file, 'calls=%d %d' % (
153
subentry.callcount, code.co_firstlineno)
197
if isinstance(code, str):
198
print >> out_file, 'cfi=~'
199
print >> out_file, 'calls=%d 0' % (subentry.callcount,)
201
print >> out_file, 'cfi=%s' % (code.co_filename,)
202
print >> out_file, 'calls=%d %d' % (
203
subentry.callcount, code.co_firstlineno)
154
204
print >> out_file, '%d %d' % (lineno, totaltime)
159
208
def label(code, calltree=False):