##// END OF EJS Templates
py3: use %d to format ints...
Gregory Szorc -
r40229:b25fbe7e default
parent child Browse files
Show More
@@ -1,121 +1,121 b''
1 1 from __future__ import absolute_import, print_function
2 2
3 3 import _lsprof
4 4 import sys
5 5
6 6 Profiler = _lsprof.Profiler
7 7
8 8 # PyPy doesn't expose profiler_entry from the module.
9 9 profiler_entry = getattr(_lsprof, 'profiler_entry', None)
10 10
11 11 __all__ = ['profile', 'Stats']
12 12
13 13 def profile(f, *args, **kwds):
14 14 """XXX docstring"""
15 15 p = Profiler()
16 16 p.enable(subcalls=True, builtins=True)
17 17 try:
18 18 f(*args, **kwds)
19 19 finally:
20 20 p.disable()
21 21 return Stats(p.getstats())
22 22
23 23
24 24 class Stats(object):
25 25 """XXX docstring"""
26 26
27 27 def __init__(self, data):
28 28 self.data = data
29 29
30 30 def sort(self, crit=r"inlinetime"):
31 31 """XXX docstring"""
32 32 # profiler_entries isn't defined when running under PyPy.
33 33 if profiler_entry:
34 34 if crit not in profiler_entry.__dict__:
35 35 raise ValueError("Can't sort by %s" % crit)
36 36 elif self.data and not getattr(self.data[0], crit, None):
37 37 raise ValueError("Can't sort by %s" % crit)
38 38
39 39 self.data.sort(key=lambda x: getattr(x, crit), reverse=True)
40 40 for e in self.data:
41 41 if e.calls:
42 42 e.calls.sort(key=lambda x: getattr(x, crit), reverse=True)
43 43
44 44 def pprint(self, top=None, file=None, limit=None, climit=None):
45 45 """XXX docstring"""
46 46 if file is None:
47 47 file = sys.stdout
48 48 d = self.data
49 49 if top is not None:
50 50 d = d[:top]
51 cols = "% 12s %12s %11.4f %11.4f %s\n"
51 cols = "% 12d %12d %11.4f %11.4f %s\n"
52 52 hcols = "% 12s %12s %12s %12s %s\n"
53 53 file.write(hcols % ("CallCount", "Recursive", "Total(s)",
54 54 "Inline(s)", "module:lineno(function)"))
55 55 count = 0
56 56 for e in d:
57 57 file.write(cols % (e.callcount, e.reccallcount, e.totaltime,
58 58 e.inlinetime, label(e.code)))
59 59 count += 1
60 60 if limit is not None and count == limit:
61 61 return
62 62 ccount = 0
63 63 if climit and e.calls:
64 64 for se in e.calls:
65 65 file.write(cols % (se.callcount, se.reccallcount,
66 66 se.totaltime, se.inlinetime,
67 67 " %s" % label(se.code)))
68 68 count += 1
69 69 ccount += 1
70 70 if limit is not None and count == limit:
71 71 return
72 72 if climit is not None and ccount == climit:
73 73 break
74 74
75 75 def freeze(self):
76 76 """Replace all references to code objects with string
77 77 descriptions; this makes it possible to pickle the instance."""
78 78
79 79 # this code is probably rather ickier than it needs to be!
80 80 for i in range(len(self.data)):
81 81 e = self.data[i]
82 82 if not isinstance(e.code, str):
83 83 self.data[i] = type(e)((label(e.code),) + e[1:])
84 84 if e.calls:
85 85 for j in range(len(e.calls)):
86 86 se = e.calls[j]
87 87 if not isinstance(se.code, str):
88 88 e.calls[j] = type(se)((label(se.code),) + se[1:])
89 89
90 90 _fn2mod = {}
91 91
92 92 def label(code):
93 93 if isinstance(code, str):
94 94 return code
95 95 try:
96 96 mname = _fn2mod[code.co_filename]
97 97 except KeyError:
98 98 for k, v in list(sys.modules.iteritems()):
99 99 if v is None:
100 100 continue
101 101 if not isinstance(getattr(v, '__file__', None), str):
102 102 continue
103 103 if v.__file__.startswith(code.co_filename):
104 104 mname = _fn2mod[code.co_filename] = k
105 105 break
106 106 else:
107 107 mname = _fn2mod[code.co_filename] = '<%s>' % code.co_filename
108 108
109 109 return '%s:%d(%s)' % (mname, code.co_firstlineno, code.co_name)
110 110
111 111
112 112 if __name__ == '__main__':
113 113 import os
114 114 sys.argv = sys.argv[1:]
115 115 if not sys.argv:
116 116 print("usage: lsprof.py <script> <arguments...>", file=sys.stderr)
117 117 sys.exit(2)
118 118 sys.path.insert(0, os.path.abspath(os.path.dirname(sys.argv[0])))
119 119 stats = profile(execfile, sys.argv[0], globals(), locals())
120 120 stats.sort()
121 121 stats.pprint()
General Comments 0
You need to be logged in to leave comments. Login now