Mercurial > hg
annotate mercurial/profiling.py @ 30401:869d660b8669
debugcommands: introduce standalone module for debug commands
commands.py is our largest .py file by nearly 2x. Debug commands live
in a world of their own. So let's extract them to their own module.
We start with "debugancestor."
We currently reuse the commands table with commands.py and have a hack
in dispatch.py for loading debugcommands.py. In the future, we could
potentially use a separate commands table and avoid the import of
debugcommands.py.
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Wed, 17 Aug 2016 21:07:38 -0700 |
parents | 189a1030affb |
children | 69acfd2ca11e |
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 import os |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
12 import time |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
13 |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
14 from .i18n import _ |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
15 from . import ( |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
16 error, |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
17 util, |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
18 ) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
19 |
29783
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
20 @contextlib.contextmanager |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
21 def lsprofile(ui, fp): |
29781
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
22 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
|
23 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
|
24 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
|
25 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
|
26 |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
27 if format not in ['text', 'kcachegrind']: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
28 ui.warn(_("unrecognized profiling format '%s'" |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
29 " - Ignored\n") % format) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
30 format = 'text' |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
31 |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
32 try: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
33 from . import lsprof |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
34 except ImportError: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
35 raise error.Abort(_( |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
36 'lsprof not available - install from ' |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
37 '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
|
38 p = lsprof.Profiler() |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
39 p.enable(subcalls=True) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
40 try: |
29783
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
41 yield |
29781
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
42 finally: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
43 p.disable() |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
44 |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
45 if format == 'kcachegrind': |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
46 from . import lsprofcalltree |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
47 calltree = lsprofcalltree.KCacheGrind(p) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
48 calltree.output(fp) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
49 else: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
50 # format == 'text' |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
51 stats = lsprof.Stats(p.getstats()) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
52 stats.sort(field) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
53 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
|
54 |
29783
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
55 @contextlib.contextmanager |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
56 def flameprofile(ui, fp): |
29781
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
57 try: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
58 from flamegraph import flamegraph |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
59 except ImportError: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
60 raise error.Abort(_( |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
61 'flamegraph not available - install from ' |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
62 'https://github.com/evanhempel/python-flamegraph')) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
63 # developer config: profiling.freq |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
64 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
|
65 filter_ = None |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
66 collapse_recursion = True |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
67 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
|
68 filter_, collapse_recursion) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
69 start_time = time.clock() |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
70 try: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
71 thread.start() |
29783
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
72 yield |
29781
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
73 finally: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
74 thread.stop() |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
75 thread.join() |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
76 print('Collected %d stack frames (%d unique) in %2.2f seconds.' % ( |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
77 time.clock() - start_time, thread.num_frames(), |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
78 thread.num_frames(unique=True))) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
79 |
29783
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
80 @contextlib.contextmanager |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
81 def statprofile(ui, fp): |
30316
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29785
diff
changeset
|
82 from . import statprof |
29781
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
83 |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
84 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
|
85 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
|
86 # 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
|
87 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
|
88 statprof.reset(freq) |
29781
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
89 else: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
90 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
|
91 |
30316
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29785
diff
changeset
|
92 statprof.start(mechanism='thread') |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29785
diff
changeset
|
93 |
29781
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
94 try: |
29783
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
95 yield |
29781
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
96 finally: |
30316
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29785
diff
changeset
|
97 data = statprof.stop() |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29785
diff
changeset
|
98 |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29785
diff
changeset
|
99 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
|
100 |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29785
diff
changeset
|
101 formats = { |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29785
diff
changeset
|
102 'byline': statprof.DisplayFormats.ByLine, |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29785
diff
changeset
|
103 'bymethod': statprof.DisplayFormats.ByMethod, |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29785
diff
changeset
|
104 'hotpath': statprof.DisplayFormats.Hotpath, |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29785
diff
changeset
|
105 'json': statprof.DisplayFormats.Json, |
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 |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29785
diff
changeset
|
114 statprof.display(fp, data=data, format=displayformat) |
29781
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
115 |
29783
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
116 @contextlib.contextmanager |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
117 def profile(ui): |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
118 """Start profiling. |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
119 |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
120 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
|
121 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
|
122 """ |
29781
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
123 profiler = os.getenv('HGPROF') |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
124 if profiler is None: |
30317
3fd53cc1aad8
profiling: make statprof the default profiler (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30316
diff
changeset
|
125 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
|
126 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
|
127 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
|
128 profiler = 'stat' |
29781
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
129 |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
130 output = ui.config('profiling', 'output') |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
131 |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
132 if output == 'blackbox': |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
133 fp = util.stringio() |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
134 elif output: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
135 path = ui.expandpath(output) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
136 fp = open(path, 'wb') |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
137 else: |
30322
189a1030affb
profiling: obtain stderr from ui
Yuya Nishihara <yuya@tcha.org>
parents:
30317
diff
changeset
|
138 fp = ui.ferr |
29781
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
139 |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
140 try: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
141 if profiler == 'ls': |
29783
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
142 proffn = lsprofile |
29781
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
143 elif profiler == 'flame': |
29783
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
144 proffn = flameprofile |
29781
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
145 else: |
29783
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
146 proffn = statprofile |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
147 |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
148 with proffn(ui, fp): |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
149 yield |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29781
diff
changeset
|
150 |
29781
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
151 finally: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
152 if output: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
153 if output == 'blackbox': |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
154 val = 'Profile:\n%s' % fp.getvalue() |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
155 # 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
|
156 # 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
|
157 val = val.replace('%', '%%') |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
158 ui.log('profile', val) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
159 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
|
160 |
e3501546f7e4
profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29783
diff
changeset
|
161 @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
|
162 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
|
163 """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
|
164 |
e3501546f7e4
profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29783
diff
changeset
|
165 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
|
166 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
|
167 |
e3501546f7e4
profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29783
diff
changeset
|
168 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
|
169 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
|
170 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
|
171 """ |
e3501546f7e4
profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29783
diff
changeset
|
172 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
|
173 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
|
174 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
|
175 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
|
176 yield |