Mercurial > public > mercurial-scm > hg
comparison mercurial/profiling.py @ 30316:faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Now that the statprof module is vendored and suitable for use, we
switch our statprof profiler to use it. This required some minor
changes because of drift between the official statprof profiler
and the vendored copy.
We also incorporate Facebook's improvements from the "statprofext"
extension at
https://bitbucket.org/facebook/hg-experimental, notably support for
different display formats.
Because statprof output is different, this is marked as BC. Although
most users likely won't notice since most users don't profile.
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Fri, 04 Nov 2016 20:50:38 -0700 |
parents | 88d3c1ab03a7 |
children | 3fd53cc1aad8 |
comparison
equal
deleted
inserted
replaced
30315:0911191dc4c9 | 30316:faf1b8923da2 |
---|---|
78 time.clock() - start_time, thread.num_frames(), | 78 time.clock() - start_time, thread.num_frames(), |
79 thread.num_frames(unique=True))) | 79 thread.num_frames(unique=True))) |
80 | 80 |
81 @contextlib.contextmanager | 81 @contextlib.contextmanager |
82 def statprofile(ui, fp): | 82 def statprofile(ui, fp): |
83 try: | 83 from . import statprof |
84 import statprof | |
85 except ImportError: | |
86 raise error.Abort(_( | |
87 'statprof not available - install using "easy_install statprof"')) | |
88 | 84 |
89 freq = ui.configint('profiling', 'freq', default=1000) | 85 freq = ui.configint('profiling', 'freq', default=1000) |
90 if freq > 0: | 86 if freq > 0: |
91 # Cannot reset when profiler is already active. So silently no-op. | 87 # Cannot reset when profiler is already active. So silently no-op. |
92 if statprof.state.profile_level == 0: | 88 if statprof.state.profile_level == 0: |
93 statprof.reset(freq) | 89 statprof.reset(freq) |
94 else: | 90 else: |
95 ui.warn(_("invalid sampling frequency '%s' - ignoring\n") % freq) | 91 ui.warn(_("invalid sampling frequency '%s' - ignoring\n") % freq) |
96 | 92 |
97 statprof.start() | 93 statprof.start(mechanism='thread') |
94 | |
98 try: | 95 try: |
99 yield | 96 yield |
100 finally: | 97 finally: |
101 statprof.stop() | 98 data = statprof.stop() |
102 statprof.display(fp) | 99 |
100 profformat = ui.config('profiling', 'statformat', 'hotpath') | |
101 | |
102 formats = { | |
103 'byline': statprof.DisplayFormats.ByLine, | |
104 'bymethod': statprof.DisplayFormats.ByMethod, | |
105 'hotpath': statprof.DisplayFormats.Hotpath, | |
106 'json': statprof.DisplayFormats.Json, | |
107 } | |
108 | |
109 if profformat in formats: | |
110 displayformat = formats[profformat] | |
111 else: | |
112 ui.warn(_('unknown profiler output format: %s\n') % profformat) | |
113 displayformat = statprof.DisplayFormats.Hotpath | |
114 | |
115 statprof.display(fp, data=data, format=displayformat) | |
103 | 116 |
104 @contextlib.contextmanager | 117 @contextlib.contextmanager |
105 def profile(ui): | 118 def profile(ui): |
106 """Start profiling. | 119 """Start profiling. |
107 | 120 |