106
104
"""Output profiling data in calltree format (for KCacheGrind)."""
107
105
_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)
136
108
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
146
110
def __init__(self, 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=~'
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
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
180
138
calls = entry.calls
183
if isinstance(code, str):
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
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,)
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)
208
159
def label(code, calltree=False):