Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/profiling.py @ 32455:f40dc6f7c12f
profiling: allow loading profiling extension before everything else
6d642ecf1a89 makes profiler start early without loading extensions. That
makes it impossible for an extension to add customized profilers.
This patch adds a special case: if a profiler is not found but an extension
with the same name could be loaded, load that extension first, and expect it
to have a "profile" contextmanager method. This allows customized profilers
and extension setup time is still profiled.
author | Jun Wu <quark@fb.com> |
---|---|
date | Mon, 22 May 2017 01:17:49 -0700 |
parents | 22fbca1d11ed |
children | 4483696dacee |
comparison
equal
deleted
inserted
replaced
32454:9a3e88d4a030 | 32455:f40dc6f7c12f |
---|---|
11 | 11 |
12 from .i18n import _ | 12 from .i18n import _ |
13 from . import ( | 13 from . import ( |
14 encoding, | 14 encoding, |
15 error, | 15 error, |
16 extensions, | |
16 util, | 17 util, |
17 ) | 18 ) |
19 | |
20 def _loadprofiler(ui, profiler): | |
21 """load profiler extension. return profile method, or None on failure""" | |
22 extname = profiler | |
23 extensions.loadall(ui, whitelist=[extname]) | |
24 try: | |
25 mod = extensions.find(extname) | |
26 except KeyError: | |
27 return None | |
28 else: | |
29 return getattr(mod, 'profile', None) | |
18 | 30 |
19 @contextlib.contextmanager | 31 @contextlib.contextmanager |
20 def lsprofile(ui, fp): | 32 def lsprofile(ui, fp): |
21 format = ui.config('profiling', 'format', default='text') | 33 format = ui.config('profiling', 'format', default='text') |
22 field = ui.config('profiling', 'sort', default='inlinetime') | 34 field = ui.config('profiling', 'sort', default='inlinetime') |
135 | 147 |
136 Profiling is active when the context manager is active. When the context | 148 Profiling is active when the context manager is active. When the context |
137 manager exits, profiling results will be written to the configured output. | 149 manager exits, profiling results will be written to the configured output. |
138 """ | 150 """ |
139 profiler = encoding.environ.get('HGPROF') | 151 profiler = encoding.environ.get('HGPROF') |
152 proffn = None | |
140 if profiler is None: | 153 if profiler is None: |
141 profiler = ui.config('profiling', 'type', default='stat') | 154 profiler = ui.config('profiling', 'type', default='stat') |
142 if profiler not in ('ls', 'stat', 'flame'): | 155 if profiler not in ('ls', 'stat', 'flame'): |
143 ui.warn(_("unrecognized profiler '%s' - ignored\n") % profiler) | 156 # try load profiler from extension with the same name |
144 profiler = 'stat' | 157 proffn = _loadprofiler(ui, profiler) |
158 if proffn is None: | |
159 ui.warn(_("unrecognized profiler '%s' - ignored\n") % profiler) | |
160 profiler = 'stat' | |
145 | 161 |
146 output = ui.config('profiling', 'output') | 162 output = ui.config('profiling', 'output') |
147 | 163 |
148 if output == 'blackbox': | 164 if output == 'blackbox': |
149 fp = util.stringio() | 165 fp = util.stringio() |
152 fp = open(path, 'wb') | 168 fp = open(path, 'wb') |
153 else: | 169 else: |
154 fp = ui.ferr | 170 fp = ui.ferr |
155 | 171 |
156 try: | 172 try: |
157 if profiler == 'ls': | 173 if proffn is not None: |
174 pass | |
175 elif profiler == 'ls': | |
158 proffn = lsprofile | 176 proffn = lsprofile |
159 elif profiler == 'flame': | 177 elif profiler == 'flame': |
160 proffn = flameprofile | 178 proffn = flameprofile |
161 else: | 179 else: |
162 proffn = statprofile | 180 proffn = statprofile |