annotate mercurial/profiling.py @ 31060:ab20491b1760

dispatch: rearrange 'unknown command' code to better employ pager dispatch calls help like a ninja if you give it a truly unknown command, and that might want to be paged. If it gets paged, then the 'hg: unknown command' text gets eaten by a grue, unless we call the pager first. This change rearranges the codepaths so we can safely only invoke the pager in the case where we'll have long output from the help command code, rather than just a short message like "did you mean stat instead of start" or "fetch is provided by the fetch extension".
author Augie Fackler <augie@google.com>
date Tue, 21 Feb 2017 14:20:05 -0500
parents 22fbca1d11ed
children f40dc6f7c12f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1 # profiling.py - profiling functions
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
2 #
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
3 # Copyright 2016 Gregory Szorc <gregory.szorc@gmail.com>
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
4 #
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms of the
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
6 # GNU General Public License version 2 or any later version.
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
7
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
8 from __future__ import absolute_import, print_function
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
9
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
10 import contextlib
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
11
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
12 from .i18n import _
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
13 from . import (
30820
6a70cf94d1b5 py3: replace pycompat.getenv with encoding.environ.get
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30664
diff changeset
14 encoding,
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
15 error,
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
16 util,
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
17 )
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
18
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
19 @contextlib.contextmanager
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
20 def lsprofile(ui, fp):
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
21 format = ui.config('profiling', 'format', default='text')
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
22 field = ui.config('profiling', 'sort', default='inlinetime')
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
23 limit = ui.configint('profiling', 'limit', default=30)
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
24 climit = ui.configint('profiling', 'nested', default=0)
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
25
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
26 if format not in ['text', 'kcachegrind']:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
27 ui.warn(_("unrecognized profiling format '%s'"
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
28 " - Ignored\n") % format)
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
29 format = 'text'
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
30
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
31 try:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
32 from . import lsprof
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
33 except ImportError:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
34 raise error.Abort(_(
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
35 'lsprof not available - install from '
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
36 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
37 p = lsprof.Profiler()
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
38 p.enable(subcalls=True)
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
39 try:
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
40 yield
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
41 finally:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
42 p.disable()
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
43
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
44 if format == 'kcachegrind':
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
45 from . import lsprofcalltree
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
46 calltree = lsprofcalltree.KCacheGrind(p)
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
47 calltree.output(fp)
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
48 else:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
49 # format == 'text'
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
50 stats = lsprof.Stats(p.getstats())
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
51 stats.sort(field)
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
52 stats.pprint(limit=limit, file=fp, climit=climit)
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
53
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
54 @contextlib.contextmanager
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
55 def flameprofile(ui, fp):
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
56 try:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
57 from flamegraph import flamegraph
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
58 except ImportError:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
59 raise error.Abort(_(
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
60 'flamegraph not available - install from '
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
61 'https://github.com/evanhempel/python-flamegraph'))
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
62 # developer config: profiling.freq
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
63 freq = ui.configint('profiling', 'freq', default=1000)
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
64 filter_ = None
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
65 collapse_recursion = True
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
66 thread = flamegraph.ProfileThread(fp, 1.0 / freq,
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
67 filter_, collapse_recursion)
30975
22fbca1d11ed mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents: 30930
diff changeset
68 start_time = util.timer()
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
69 try:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
70 thread.start()
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
71 yield
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
72 finally:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
73 thread.stop()
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
74 thread.join()
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
75 print('Collected %d stack frames (%d unique) in %2.2f seconds.' % (
30975
22fbca1d11ed mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents: 30930
diff changeset
76 util.timer() - start_time, thread.num_frames(),
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
77 thread.num_frames(unique=True)))
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
78
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
79 @contextlib.contextmanager
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
80 def statprofile(ui, fp):
30316
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
81 from . import statprof
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
82
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
83 freq = ui.configint('profiling', 'freq', default=1000)
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
84 if freq > 0:
29785
88d3c1ab03a7 profiling: don't error with statprof when profiling has already started
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29784
diff changeset
85 # Cannot reset when profiler is already active. So silently no-op.
88d3c1ab03a7 profiling: don't error with statprof when profiling has already started
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29784
diff changeset
86 if statprof.state.profile_level == 0:
88d3c1ab03a7 profiling: don't error with statprof when profiling has already started
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29784
diff changeset
87 statprof.reset(freq)
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
88 else:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
89 ui.warn(_("invalid sampling frequency '%s' - ignoring\n") % freq)
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
90
30316
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
91 statprof.start(mechanism='thread')
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
92
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
93 try:
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
94 yield
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
95 finally:
30316
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
96 data = statprof.stop()
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
97
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
98 profformat = ui.config('profiling', 'statformat', 'hotpath')
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
99
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
100 formats = {
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
101 'byline': statprof.DisplayFormats.ByLine,
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
102 'bymethod': statprof.DisplayFormats.ByMethod,
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
103 'hotpath': statprof.DisplayFormats.Hotpath,
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
104 'json': statprof.DisplayFormats.Json,
30930
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
105 'chrome': statprof.DisplayFormats.Chrome,
30316
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
106 }
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
107
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
108 if profformat in formats:
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
109 displayformat = formats[profformat]
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
110 else:
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
111 ui.warn(_('unknown profiler output format: %s\n') % profformat)
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
112 displayformat = statprof.DisplayFormats.Hotpath
faf1b8923da2 profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29785
diff changeset
113
30930
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
114 kwargs = {}
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
115
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
116 def fraction(s):
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
117 if s.endswith('%'):
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
118 v = float(s[:-1]) / 100
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
119 else:
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
120 v = float(s)
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
121 if 0 <= v <= 1:
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
122 return v
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
123 raise ValueError(s)
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
124
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
125 if profformat == 'chrome':
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
126 showmin = ui.configwith(fraction, 'profiling', 'showmin', 0.005)
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
127 showmax = ui.configwith(fraction, 'profiling', 'showmax', 0.999)
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
128 kwargs.update(minthreshold=showmin, maxthreshold=showmax)
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
129
517bc1cd7033 profiling: add statprof support for Chrome trace viewer rendering
Bryan O'Sullivan <bryano@fb.com>
parents: 30820
diff changeset
130 statprof.display(fp, data=data, format=displayformat, **kwargs)
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
131
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
132 @contextlib.contextmanager
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
133 def profile(ui):
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
134 """Start profiling.
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
135
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
136 Profiling is active when the context manager is active. When the context
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
137 manager exits, profiling results will be written to the configured output.
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
138 """
30820
6a70cf94d1b5 py3: replace pycompat.getenv with encoding.environ.get
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30664
diff changeset
139 profiler = encoding.environ.get('HGPROF')
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
140 if profiler is None:
30317
3fd53cc1aad8 profiling: make statprof the default profiler (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30316
diff changeset
141 profiler = ui.config('profiling', 'type', default='stat')
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
142 if profiler not in ('ls', 'stat', 'flame'):
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
143 ui.warn(_("unrecognized profiler '%s' - ignored\n") % profiler)
30317
3fd53cc1aad8 profiling: make statprof the default profiler (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30316
diff changeset
144 profiler = 'stat'
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
145
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
146 output = ui.config('profiling', 'output')
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
147
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
148 if output == 'blackbox':
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
149 fp = util.stringio()
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
150 elif output:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
151 path = ui.expandpath(output)
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
152 fp = open(path, 'wb')
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
153 else:
30322
189a1030affb profiling: obtain stderr from ui
Yuya Nishihara <yuya@tcha.org>
parents: 30317
diff changeset
154 fp = ui.ferr
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
155
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
156 try:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
157 if profiler == 'ls':
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
158 proffn = lsprofile
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
159 elif profiler == 'flame':
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
160 proffn = flameprofile
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
161 else:
29783
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
162 proffn = statprofile
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
163
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
164 with proffn(ui, fp):
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
165 yield
5d44197c208b profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29781
diff changeset
166
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
167 finally:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
168 if output:
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
169 if output == 'blackbox':
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
170 val = 'Profile:\n%s' % fp.getvalue()
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
171 # ui.log treats the input as a format string,
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
172 # so we need to escape any % signs.
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
173 val = val.replace('%', '%%')
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
174 ui.log('profile', val)
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
175 fp.close()
29784
e3501546f7e4 profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29783
diff changeset
176
e3501546f7e4 profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29783
diff changeset
177 @contextlib.contextmanager
e3501546f7e4 profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29783
diff changeset
178 def maybeprofile(ui):
e3501546f7e4 profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29783
diff changeset
179 """Profile if enabled, else do nothing.
e3501546f7e4 profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29783
diff changeset
180
e3501546f7e4 profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29783
diff changeset
181 This context manager can be used to optionally profile if profiling
e3501546f7e4 profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29783
diff changeset
182 is enabled. Otherwise, it does nothing.
e3501546f7e4 profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29783
diff changeset
183
e3501546f7e4 profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29783
diff changeset
184 The purpose of this context manager is to make calling code simpler:
e3501546f7e4 profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29783
diff changeset
185 just use a single code path for calling into code you may want to profile
e3501546f7e4 profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29783
diff changeset
186 and this function determines whether to start profiling.
e3501546f7e4 profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29783
diff changeset
187 """
e3501546f7e4 profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29783
diff changeset
188 if ui.configbool('profiling', 'enabled'):
e3501546f7e4 profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29783
diff changeset
189 with profile(ui):
e3501546f7e4 profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29783
diff changeset
190 yield
e3501546f7e4 profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29783
diff changeset
191 else:
e3501546f7e4 profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29783
diff changeset
192 yield