Mercurial > public > mercurial-scm > hg
comparison mercurial/profiling.py @ 43076:2372284d9457
formatting: blacken the codebase
This is using my patch to black
(https://github.com/psf/black/pull/826) so we don't un-wrap collection
literals.
Done with:
hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S
# skip-blame mass-reformatting only
# no-check-commit reformats foo_bar functions
Differential Revision: https://phab.mercurial-scm.org/D6971
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 06 Oct 2019 09:45:02 -0400 |
parents | 0ae593e791fb |
children | 687b865b95ad |
comparison
equal
deleted
inserted
replaced
43075:57875cf423c9 | 43076:2372284d9457 |
---|---|
16 extensions, | 16 extensions, |
17 pycompat, | 17 pycompat, |
18 util, | 18 util, |
19 ) | 19 ) |
20 | 20 |
21 | |
21 def _loadprofiler(ui, profiler): | 22 def _loadprofiler(ui, profiler): |
22 """load profiler extension. return profile method, or None on failure""" | 23 """load profiler extension. return profile method, or None on failure""" |
23 extname = profiler | 24 extname = profiler |
24 extensions.loadall(ui, whitelist=[extname]) | 25 extensions.loadall(ui, whitelist=[extname]) |
25 try: | 26 try: |
26 mod = extensions.find(extname) | 27 mod = extensions.find(extname) |
27 except KeyError: | 28 except KeyError: |
28 return None | 29 return None |
29 else: | 30 else: |
30 return getattr(mod, 'profile', None) | 31 return getattr(mod, 'profile', None) |
32 | |
31 | 33 |
32 @contextlib.contextmanager | 34 @contextlib.contextmanager |
33 def lsprofile(ui, fp): | 35 def lsprofile(ui, fp): |
34 format = ui.config('profiling', 'format') | 36 format = ui.config('profiling', 'format') |
35 field = ui.config('profiling', 'sort') | 37 field = ui.config('profiling', 'sort') |
36 limit = ui.configint('profiling', 'limit') | 38 limit = ui.configint('profiling', 'limit') |
37 climit = ui.configint('profiling', 'nested') | 39 climit = ui.configint('profiling', 'nested') |
38 | 40 |
39 if format not in ['text', 'kcachegrind']: | 41 if format not in ['text', 'kcachegrind']: |
40 ui.warn(_("unrecognized profiling format '%s'" | 42 ui.warn(_("unrecognized profiling format '%s'" " - Ignored\n") % format) |
41 " - Ignored\n") % format) | |
42 format = 'text' | 43 format = 'text' |
43 | 44 |
44 try: | 45 try: |
45 from . import lsprof | 46 from . import lsprof |
46 except ImportError: | 47 except ImportError: |
47 raise error.Abort(_( | 48 raise error.Abort( |
48 'lsprof not available - install from ' | 49 _( |
49 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/')) | 50 'lsprof not available - install from ' |
51 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/' | |
52 ) | |
53 ) | |
50 p = lsprof.Profiler() | 54 p = lsprof.Profiler() |
51 p.enable(subcalls=True) | 55 p.enable(subcalls=True) |
52 try: | 56 try: |
53 yield | 57 yield |
54 finally: | 58 finally: |
55 p.disable() | 59 p.disable() |
56 | 60 |
57 if format == 'kcachegrind': | 61 if format == 'kcachegrind': |
58 from . import lsprofcalltree | 62 from . import lsprofcalltree |
63 | |
59 calltree = lsprofcalltree.KCacheGrind(p) | 64 calltree = lsprofcalltree.KCacheGrind(p) |
60 calltree.output(fp) | 65 calltree.output(fp) |
61 else: | 66 else: |
62 # format == 'text' | 67 # format == 'text' |
63 stats = lsprof.Stats(p.getstats()) | 68 stats = lsprof.Stats(p.getstats()) |
64 stats.sort(pycompat.sysstr(field)) | 69 stats.sort(pycompat.sysstr(field)) |
65 stats.pprint(limit=limit, file=fp, climit=climit) | 70 stats.pprint(limit=limit, file=fp, climit=climit) |
66 | 71 |
72 | |
67 @contextlib.contextmanager | 73 @contextlib.contextmanager |
68 def flameprofile(ui, fp): | 74 def flameprofile(ui, fp): |
69 try: | 75 try: |
70 from flamegraph import flamegraph | 76 from flamegraph import flamegraph |
71 except ImportError: | 77 except ImportError: |
72 raise error.Abort(_( | 78 raise error.Abort( |
73 'flamegraph not available - install from ' | 79 _( |
74 'https://github.com/evanhempel/python-flamegraph')) | 80 'flamegraph not available - install from ' |
81 'https://github.com/evanhempel/python-flamegraph' | |
82 ) | |
83 ) | |
75 # developer config: profiling.freq | 84 # developer config: profiling.freq |
76 freq = ui.configint('profiling', 'freq') | 85 freq = ui.configint('profiling', 'freq') |
77 filter_ = None | 86 filter_ = None |
78 collapse_recursion = True | 87 collapse_recursion = True |
79 thread = flamegraph.ProfileThread(fp, 1.0 / freq, | 88 thread = flamegraph.ProfileThread( |
80 filter_, collapse_recursion) | 89 fp, 1.0 / freq, filter_, collapse_recursion |
90 ) | |
81 start_time = util.timer() | 91 start_time = util.timer() |
82 try: | 92 try: |
83 thread.start() | 93 thread.start() |
84 yield | 94 yield |
85 finally: | 95 finally: |
86 thread.stop() | 96 thread.stop() |
87 thread.join() | 97 thread.join() |
88 print('Collected %d stack frames (%d unique) in %2.2f seconds.' % ( | 98 print( |
89 util.timer() - start_time, thread.num_frames(), | 99 'Collected %d stack frames (%d unique) in %2.2f seconds.' |
90 thread.num_frames(unique=True))) | 100 % ( |
101 util.timer() - start_time, | |
102 thread.num_frames(), | |
103 thread.num_frames(unique=True), | |
104 ) | |
105 ) | |
106 | |
91 | 107 |
92 @contextlib.contextmanager | 108 @contextlib.contextmanager |
93 def statprofile(ui, fp): | 109 def statprofile(ui, fp): |
94 from . import statprof | 110 from . import statprof |
95 | 111 |
99 if statprof.state.profile_level == 0: | 115 if statprof.state.profile_level == 0: |
100 statprof.reset(freq) | 116 statprof.reset(freq) |
101 else: | 117 else: |
102 ui.warn(_("invalid sampling frequency '%s' - ignoring\n") % freq) | 118 ui.warn(_("invalid sampling frequency '%s' - ignoring\n") % freq) |
103 | 119 |
104 track = ui.config('profiling', 'time-track', | 120 track = ui.config( |
105 pycompat.iswindows and 'cpu' or 'real') | 121 'profiling', 'time-track', pycompat.iswindows and 'cpu' or 'real' |
122 ) | |
106 statprof.start(mechanism='thread', track=track) | 123 statprof.start(mechanism='thread', track=track) |
107 | 124 |
108 try: | 125 try: |
109 yield | 126 yield |
110 finally: | 127 finally: |
150 showtime = ui.configbool('profiling', 'showtime') | 167 showtime = ui.configbool('profiling', 'showtime') |
151 kwargs[r'showtime'] = showtime | 168 kwargs[r'showtime'] = showtime |
152 | 169 |
153 statprof.display(fp, data=data, format=displayformat, **kwargs) | 170 statprof.display(fp, data=data, format=displayformat, **kwargs) |
154 | 171 |
172 | |
155 class profile(object): | 173 class profile(object): |
156 """Start profiling. | 174 """Start profiling. |
157 | 175 |
158 Profiling is active when the context manager is active. When the context | 176 Profiling is active when the context manager is active. When the context |
159 manager exits, profiling results will be written to the configured output. | 177 manager exits, profiling results will be written to the configured output. |
160 """ | 178 """ |
179 | |
161 def __init__(self, ui, enabled=True): | 180 def __init__(self, ui, enabled=True): |
162 self._ui = ui | 181 self._ui = ui |
163 self._output = None | 182 self._output = None |
164 self._fp = None | 183 self._fp = None |
165 self._fpdoclose = True | 184 self._fpdoclose = True |
191 profiler = self._ui.config('profiling', 'type') | 210 profiler = self._ui.config('profiling', 'type') |
192 if profiler not in ('ls', 'stat', 'flame'): | 211 if profiler not in ('ls', 'stat', 'flame'): |
193 # try load profiler from extension with the same name | 212 # try load profiler from extension with the same name |
194 proffn = _loadprofiler(self._ui, profiler) | 213 proffn = _loadprofiler(self._ui, profiler) |
195 if proffn is None: | 214 if proffn is None: |
196 self._ui.warn(_("unrecognized profiler '%s' - ignored\n") | 215 self._ui.warn( |
197 % profiler) | 216 _("unrecognized profiler '%s' - ignored\n") % profiler |
217 ) | |
198 profiler = 'stat' | 218 profiler = 'stat' |
199 | 219 |
200 self._output = self._ui.config('profiling', 'output') | 220 self._output = self._ui.config('profiling', 'output') |
201 | 221 |
202 try: | 222 try: |
208 elif pycompat.iswindows: | 228 elif pycompat.iswindows: |
209 # parse escape sequence by win32print() | 229 # parse escape sequence by win32print() |
210 class uifp(object): | 230 class uifp(object): |
211 def __init__(self, ui): | 231 def __init__(self, ui): |
212 self._ui = ui | 232 self._ui = ui |
233 | |
213 def write(self, data): | 234 def write(self, data): |
214 self._ui.write_err(data) | 235 self._ui.write_err(data) |
236 | |
215 def flush(self): | 237 def flush(self): |
216 self._ui.flush() | 238 self._ui.flush() |
239 | |
217 self._fpdoclose = False | 240 self._fpdoclose = False |
218 self._fp = uifp(self._ui) | 241 self._fp = uifp(self._ui) |
219 else: | 242 else: |
220 self._fpdoclose = False | 243 self._fpdoclose = False |
221 self._fp = self._ui.ferr | 244 self._fp = self._ui.ferr |
229 else: | 252 else: |
230 proffn = statprofile | 253 proffn = statprofile |
231 | 254 |
232 self._profiler = proffn(self._ui, self._fp) | 255 self._profiler = proffn(self._ui, self._fp) |
233 self._profiler.__enter__() | 256 self._profiler.__enter__() |
234 except: # re-raises | 257 except: # re-raises |
235 self._closefp() | 258 self._closefp() |
236 raise | 259 raise |
237 | 260 |
238 def __exit__(self, exception_type, exception_value, traceback): | 261 def __exit__(self, exception_type, exception_value, traceback): |
239 propagate = None | 262 propagate = None |
240 if self._profiler is not None: | 263 if self._profiler is not None: |
241 propagate = self._profiler.__exit__(exception_type, exception_value, | 264 propagate = self._profiler.__exit__( |
242 traceback) | 265 exception_type, exception_value, traceback |
266 ) | |
243 if self._output == 'blackbox': | 267 if self._output == 'blackbox': |
244 val = 'Profile:\n%s' % self._fp.getvalue() | 268 val = 'Profile:\n%s' % self._fp.getvalue() |
245 # ui.log treats the input as a format string, | 269 # ui.log treats the input as a format string, |
246 # so we need to escape any % signs. | 270 # so we need to escape any % signs. |
247 val = val.replace('%', '%%') | 271 val = val.replace('%', '%%') |