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