##// END OF EJS Templates
py3: use util.forcebytestr to convert error messages to bytes...
py3: use util.forcebytestr to convert error messages to bytes Differential Revision: https://phab.mercurial-scm.org/D2421

File last commit:

r35854:d4e5b265 default
r36414:743b293c default
Show More
lsprof.py
121 lines | 4.0 KiB | text/x-python | PythonLexer
Gregory Szorc
lsprof: use print function
r27617 from __future__ import absolute_import, print_function
Gregory Szorc
lsprof: support PyPy (issue4573)...
r27061
import _lsprof
Vadim Gelfer
add --lsprof option. 3x faster than --profile, more useful output....
r2422 import sys
Gregory Szorc
lsprof: support PyPy (issue4573)...
r27061
Profiler = _lsprof.Profiler
# PyPy doesn't expose profiler_entry from the module.
profiler_entry = getattr(_lsprof, 'profiler_entry', None)
Vadim Gelfer
add --lsprof option. 3x faster than --profile, more useful output....
r2422
__all__ = ['profile', 'Stats']
def profile(f, *args, **kwds):
"""XXX docstring"""
p = Profiler()
Dirkjan Ochtman
updating lsprof.py from remote repository
r5992 p.enable(subcalls=True, builtins=True)
Vadim Gelfer
add --lsprof option. 3x faster than --profile, more useful output....
r2422 try:
Dirkjan Ochtman
updating lsprof.py from remote repository
r5992 f(*args, **kwds)
Vadim Gelfer
add --lsprof option. 3x faster than --profile, more useful output....
r2422 finally:
p.disable()
Dirkjan Ochtman
updating lsprof.py from remote repository
r5992 return Stats(p.getstats())
Vadim Gelfer
add --lsprof option. 3x faster than --profile, more useful output....
r2422
class Stats(object):
"""XXX docstring"""
def __init__(self, data):
self.data = data
Augie Fackler
lsprof: use native string when peeking in __dict__...
r35854 def sort(self, crit=r"inlinetime"):
Vadim Gelfer
add --lsprof option. 3x faster than --profile, more useful output....
r2422 """XXX docstring"""
Gregory Szorc
lsprof: support PyPy (issue4573)...
r27061 # profiler_entries isn't defined when running under PyPy.
if profiler_entry:
if crit not in profiler_entry.__dict__:
raise ValueError("Can't sort by %s" % crit)
elif self.data and not getattr(self.data[0], crit, None):
Peter Ruibal
use Exception(args)-style raising consistently (py3k compatibility)
r7008 raise ValueError("Can't sort by %s" % crit)
Gregory Szorc
lsprof: support PyPy (issue4573)...
r27061
Alejandro Santos
compat: use 'key' argument instead of 'cmp' when sorting a list
r9032 self.data.sort(key=lambda x: getattr(x, crit), reverse=True)
Vadim Gelfer
add --lsprof option. 3x faster than --profile, more useful output....
r2422 for e in self.data:
if e.calls:
Alejandro Santos
compat: use 'key' argument instead of 'cmp' when sorting a list
r9032 e.calls.sort(key=lambda x: getattr(x, crit), reverse=True)
Vadim Gelfer
add --lsprof option. 3x faster than --profile, more useful output....
r2422
def pprint(self, top=None, file=None, limit=None, climit=None):
"""XXX docstring"""
if file is None:
file = sys.stdout
d = self.data
if top is not None:
d = d[:top]
Dirkjan Ochtman
updating lsprof.py from remote repository
r5992 cols = "% 12s %12s %11.4f %11.4f %s\n"
hcols = "% 12s %12s %12s %12s %s\n"
Bryan O'Sullivan
lsprof: report units correctly
r16804 file.write(hcols % ("CallCount", "Recursive", "Total(s)",
"Inline(s)", "module:lineno(function)"))
Vadim Gelfer
add --lsprof option. 3x faster than --profile, more useful output....
r2422 count = 0
for e in d:
Dirkjan Ochtman
updating lsprof.py from remote repository
r5992 file.write(cols % (e.callcount, e.reccallcount, e.totaltime,
Vadim Gelfer
add --lsprof option. 3x faster than --profile, more useful output....
r2422 e.inlinetime, label(e.code)))
count += 1
if limit is not None and count == limit:
return
ccount = 0
Matt Mackall
profile: add undocumented config options for profiler output
r16263 if climit and e.calls:
Vadim Gelfer
add --lsprof option. 3x faster than --profile, more useful output....
r2422 for se in e.calls:
Mads Kiilerich
profiling: replace '+' markup of nested lines with indentation...
r18642 file.write(cols % (se.callcount, se.reccallcount,
Vadim Gelfer
add --lsprof option. 3x faster than --profile, more useful output....
r2422 se.totaltime, se.inlinetime,
Mads Kiilerich
profiling: replace '+' markup of nested lines with indentation...
r18642 " %s" % label(se.code)))
Vadim Gelfer
add --lsprof option. 3x faster than --profile, more useful output....
r2422 count += 1
ccount += 1
if limit is not None and count == limit:
return
if climit is not None and ccount == climit:
break
def freeze(self):
"""Replace all references to code objects with string
descriptions; this makes it possible to pickle the instance."""
# this code is probably rather ickier than it needs to be!
for i in range(len(self.data)):
e = self.data[i]
if not isinstance(e.code, str):
self.data[i] = type(e)((label(e.code),) + e[1:])
Dirkjan Ochtman
updating lsprof.py from remote repository
r5992 if e.calls:
for j in range(len(e.calls)):
se = e.calls[j]
if not isinstance(se.code, str):
e.calls[j] = type(se)((label(se.code),) + se[1:])
Vadim Gelfer
add --lsprof option. 3x faster than --profile, more useful output....
r2422
_fn2mod = {}
def label(code):
if isinstance(code, str):
return code
try:
mname = _fn2mod[code.co_filename]
except KeyError:
Dirkjan Ochtman
lsprof: make profile not die when imported modules changes (issue1774)
r9314 for k, v in list(sys.modules.iteritems()):
Vadim Gelfer
add --lsprof option. 3x faster than --profile, more useful output....
r2422 if v is None:
continue
Augie Fackler
lsprof: use getattr instead of hasattr
r14959 if not isinstance(getattr(v, '__file__', None), str):
Vadim Gelfer
add --lsprof option. 3x faster than --profile, more useful output....
r2422 continue
if v.__file__.startswith(code.co_filename):
mname = _fn2mod[code.co_filename] = k
break
else:
Benoit Boissinot
fix spaces/identation issues
r10339 mname = _fn2mod[code.co_filename] = '<%s>' % code.co_filename
Vadim Gelfer
add --lsprof option. 3x faster than --profile, more useful output....
r2422
return '%s:%d(%s)' % (mname, code.co_firstlineno, code.co_name)
if __name__ == '__main__':
import os
sys.argv = sys.argv[1:]
if not sys.argv:
Gregory Szorc
lsprof: use print function
r27617 print("usage: lsprof.py <script> <arguments...>", file=sys.stderr)
Vadim Gelfer
add --lsprof option. 3x faster than --profile, more useful output....
r2422 sys.exit(2)
sys.path.insert(0, os.path.abspath(os.path.dirname(sys.argv[0])))
stats = profile(execfile, sys.argv[0], globals(), locals())
stats.sort()
stats.pprint()