Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/profiling.py @ 30329: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 |
rev | line source |
---|---|
29792
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 |
29794
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
10 import contextlib |
29792
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 sys |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
13 import time |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
14 |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
15 from .i18n import _ |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
16 from . import ( |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
17 error, |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
18 util, |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
19 ) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
20 |
29794
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
21 @contextlib.contextmanager |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
22 def lsprofile(ui, fp): |
29792
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
23 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
|
24 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
|
25 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
|
26 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
|
27 |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
28 if format not in ['text', 'kcachegrind']: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
29 ui.warn(_("unrecognized profiling format '%s'" |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
30 " - Ignored\n") % format) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
31 format = 'text' |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
32 |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
33 try: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
34 from . import lsprof |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
35 except ImportError: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
36 raise error.Abort(_( |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
37 'lsprof not available - install from ' |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
38 '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
|
39 p = lsprof.Profiler() |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
40 p.enable(subcalls=True) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
41 try: |
29794
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
42 yield |
29792
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
43 finally: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
44 p.disable() |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
45 |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
46 if format == 'kcachegrind': |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
47 from . import lsprofcalltree |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
48 calltree = lsprofcalltree.KCacheGrind(p) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
49 calltree.output(fp) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
50 else: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
51 # format == 'text' |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
52 stats = lsprof.Stats(p.getstats()) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
53 stats.sort(field) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
54 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
|
55 |
29794
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
56 @contextlib.contextmanager |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
57 def flameprofile(ui, fp): |
29792
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
58 try: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
59 from flamegraph import flamegraph |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
60 except ImportError: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
61 raise error.Abort(_( |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
62 'flamegraph not available - install from ' |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
63 'https://github.com/evanhempel/python-flamegraph')) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
64 # developer config: profiling.freq |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
65 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
|
66 filter_ = None |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
67 collapse_recursion = True |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
68 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
|
69 filter_, collapse_recursion) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
70 start_time = time.clock() |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
71 try: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
72 thread.start() |
29794
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
73 yield |
29792
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
74 finally: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
75 thread.stop() |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
76 thread.join() |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
77 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
|
78 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
|
79 thread.num_frames(unique=True))) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
80 |
29794
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
81 @contextlib.contextmanager |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
82 def statprofile(ui, fp): |
30329
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29796
diff
changeset
|
83 from . import statprof |
29792
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
84 |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
85 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
|
86 if freq > 0: |
29796
88d3c1ab03a7
profiling: don't error with statprof when profiling has already started
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29795
diff
changeset
|
87 # 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:
29795
diff
changeset
|
88 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:
29795
diff
changeset
|
89 statprof.reset(freq) |
29792
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
90 else: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
91 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
|
92 |
30329
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29796
diff
changeset
|
93 statprof.start(mechanism='thread') |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29796
diff
changeset
|
94 |
29792
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
95 try: |
29794
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
96 yield |
29792
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
97 finally: |
30329
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29796
diff
changeset
|
98 data = statprof.stop() |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29796
diff
changeset
|
99 |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29796
diff
changeset
|
100 profformat = ui.config('profiling', 'statformat', 'hotpath') |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29796
diff
changeset
|
101 |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29796
diff
changeset
|
102 formats = { |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29796
diff
changeset
|
103 'byline': statprof.DisplayFormats.ByLine, |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29796
diff
changeset
|
104 'bymethod': statprof.DisplayFormats.ByMethod, |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29796
diff
changeset
|
105 'hotpath': statprof.DisplayFormats.Hotpath, |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29796
diff
changeset
|
106 'json': statprof.DisplayFormats.Json, |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29796
diff
changeset
|
107 } |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29796
diff
changeset
|
108 |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29796
diff
changeset
|
109 if profformat in formats: |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29796
diff
changeset
|
110 displayformat = formats[profformat] |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29796
diff
changeset
|
111 else: |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29796
diff
changeset
|
112 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:
29796
diff
changeset
|
113 displayformat = statprof.DisplayFormats.Hotpath |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29796
diff
changeset
|
114 |
faf1b8923da2
profiling: use vendored statprof and upstream enhancements (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29796
diff
changeset
|
115 statprof.display(fp, data=data, format=displayformat) |
29792
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
116 |
29794
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
117 @contextlib.contextmanager |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
118 def profile(ui): |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
119 """Start profiling. |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
120 |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
121 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:
29792
diff
changeset
|
122 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:
29792
diff
changeset
|
123 """ |
29792
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
124 profiler = os.getenv('HGPROF') |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
125 if profiler is None: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
126 profiler = ui.config('profiling', 'type', default='ls') |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
127 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
|
128 ui.warn(_("unrecognized profiler '%s' - ignored\n") % profiler) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
129 profiler = 'ls' |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
130 |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
131 output = ui.config('profiling', 'output') |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
132 |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
133 if output == 'blackbox': |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
134 fp = util.stringio() |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
135 elif output: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
136 path = ui.expandpath(output) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
137 fp = open(path, 'wb') |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
138 else: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
139 fp = sys.stderr |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
140 |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
141 try: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
142 if profiler == 'ls': |
29794
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
143 proffn = lsprofile |
29792
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
144 elif profiler == 'flame': |
29794
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
145 proffn = flameprofile |
29792
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
146 else: |
29794
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
147 proffn = statprofile |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
148 |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
149 with proffn(ui, fp): |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
150 yield |
5d44197c208b
profiling: make profiling functions context managers (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29792
diff
changeset
|
151 |
29792
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
152 finally: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
153 if output: |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
154 if output == 'blackbox': |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
155 val = 'Profile:\n%s' % fp.getvalue() |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
156 # 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
|
157 # 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
|
158 val = val.replace('%', '%%') |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
159 ui.log('profile', val) |
2654a0aac80d
profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
160 fp.close() |
29795
e3501546f7e4
profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29794
diff
changeset
|
161 |
e3501546f7e4
profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29794
diff
changeset
|
162 @contextlib.contextmanager |
e3501546f7e4
profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29794
diff
changeset
|
163 def maybeprofile(ui): |
e3501546f7e4
profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29794
diff
changeset
|
164 """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:
29794
diff
changeset
|
165 |
e3501546f7e4
profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29794
diff
changeset
|
166 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:
29794
diff
changeset
|
167 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:
29794
diff
changeset
|
168 |
e3501546f7e4
profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29794
diff
changeset
|
169 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:
29794
diff
changeset
|
170 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:
29794
diff
changeset
|
171 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:
29794
diff
changeset
|
172 """ |
e3501546f7e4
profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29794
diff
changeset
|
173 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:
29794
diff
changeset
|
174 with profile(ui): |
e3501546f7e4
profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29794
diff
changeset
|
175 yield |
e3501546f7e4
profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29794
diff
changeset
|
176 else: |
e3501546f7e4
profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents:
29794
diff
changeset
|
177 yield |