annotate mercurial/statprof.py @ 51858:460e80488cf0

typing: lock in correct changes from pytype 2023.04.11 -> 2023.06.16 There were a handful of other changes to the pyi files generated when updating pytype locally (and jumping from python 3.8.0 to python 3.10.11), but they were not as clear (e.g. the embedded type in a list changing from `nothing` to `Any` or similar). These looked obviously correct, and agreed with PyCharm's thoughts on the signatures. Oddly, even though pytype starting inferring `obsutil._getfilteredreason()` as returning bytes, it (correctly) complained about the None path when it was typed that way. Instead, raise a ProgrammingError if an unhandled fate is calculated. (Currently, all possibilities are handled, so this isn't reachable unless another fate is added in the future.)
author Matt Harbison <matt_harbison@yahoo.com>
date Tue, 20 Aug 2024 18:30:47 -0400
parents 933551630b0d
children 454feddab720
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1 ## statprof.py
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
2 ## Copyright (C) 2012 Bryan O'Sullivan <bos@serpentine.com>
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
3 ## Copyright (C) 2011 Alex Fraser <alex at phatcore dot com>
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
4 ## Copyright (C) 2004,2005 Andy Wingo <wingo at pobox dot com>
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
5 ## Copyright (C) 2001 Rob Browning <rlb at defaultvalue dot org>
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
6
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
7 ## This library is free software; you can redistribute it and/or
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
8 ## modify it under the terms of the GNU Lesser General Public
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
9 ## License as published by the Free Software Foundation; either
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
10 ## version 2.1 of the License, or (at your option) any later version.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
11 ##
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
12 ## This library is distributed in the hope that it will be useful,
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
13 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
14 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
15 ## Lesser General Public License for more details.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
16 ##
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
17 ## You should have received a copy of the GNU Lesser General Public
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
18 ## License along with this program; if not, contact:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
19 ##
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
20 ## Free Software Foundation Voice: +1-617-542-5942
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
21 ## 59 Temple Place - Suite 330 Fax: +1-617-542-2652
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
22 ## Boston, MA 02111-1307, USA gnu@gnu.org
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
23
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
24 """
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
25 statprof is intended to be a fairly simple statistical profiler for
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
26 python. It was ported directly from a statistical profiler for guile,
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
27 also named statprof, available from guile-lib [0].
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
28
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
29 [0] http://wingolog.org/software/guile-lib/statprof/
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
30
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
31 To start profiling, call statprof.start():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
32 >>> start()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
33
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
34 Then run whatever it is that you want to profile, for example:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
35 >>> import test.pystone; test.pystone.pystones()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
36
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
37 Then stop the profiling and print out the results:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
38 >>> stop()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
39 >>> display()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
40 % cumulative self
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
41 time seconds seconds name
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
42 26.72 1.40 0.37 pystone.py:79:Proc0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
43 13.79 0.56 0.19 pystone.py:133:Proc1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
44 13.79 0.19 0.19 pystone.py:208:Proc8
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
45 10.34 0.16 0.14 pystone.py:229:Func2
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
46 6.90 0.10 0.10 pystone.py:45:__init__
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
47 4.31 0.16 0.06 pystone.py:53:copy
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
48 ...
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
49
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
50 All of the numerical data is statistically approximate. In the
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
51 following column descriptions, and in all of statprof, "time" refers
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
52 to execution time (both user and system), not wall clock time.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
53
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
54 % time
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
55 The percent of the time spent inside the procedure itself (not
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
56 counting children).
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
57
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
58 cumulative seconds
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
59 The total number of seconds spent in the procedure, including
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
60 children.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
61
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
62 self seconds
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
63 The total number of seconds spent in the procedure itself (not
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
64 counting children).
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
65
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
66 name
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
67 The name of the procedure.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
68
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
69 By default statprof keeps the data collected from previous runs. If you
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
70 want to clear the collected data, call reset():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
71 >>> reset()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
72
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
73 reset() can also be used to change the sampling frequency from the
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
74 default of 1000 Hz. For example, to tell statprof to sample 50 times a
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
75 second:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
76 >>> reset(50)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
77
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
78 This means that statprof will sample the call stack after every 1/50 of
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
79 a second of user + system time spent running on behalf of the python
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
80 process. When your process is idle (for example, blocking in a read(),
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
81 as is the case at the listener), the clock does not advance. For this
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
82 reason statprof is not currently not suitable for profiling io-bound
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
83 operations.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
84
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
85 The profiler uses the hash of the code object itself to identify the
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
86 procedures, so it won't confuse different procedures with the same name.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
87 They will show up as two different rows in the output.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
88
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
89 Right now the profiler is quite simplistic. I cannot provide
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
90 call-graphs or other higher level information. What you see in the
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
91 table is pretty much all there is. Patches are welcome :-)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
92
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
93
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
94 Threading
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
95 ---------
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
96
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
97 Because signals only get delivered to the main thread in Python,
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
98 statprof only profiles the main thread. However because the time
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
99 reporting function uses per-process timers, the results can be
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
100 significantly off if other threads' work patterns are not similar to the
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
101 main thread's work patterns.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
102 """
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
103 # no-check-code
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
104
30270
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30269
diff changeset
105 import collections
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30269
diff changeset
106 import contextlib
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30269
diff changeset
107 import getopt
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30269
diff changeset
108 import inspect
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30269
diff changeset
109 import json
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30269
diff changeset
110 import os
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30269
diff changeset
111 import signal
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30269
diff changeset
112 import sys
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30269
diff changeset
113 import threading
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
114 import time
30270
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30269
diff changeset
115
51858
460e80488cf0 typing: lock in correct changes from pytype 2023.04.11 -> 2023.06.16
Matt Harbison <matt_harbison@yahoo.com>
parents: 51196
diff changeset
116 from typing import (
460e80488cf0 typing: lock in correct changes from pytype 2023.04.11 -> 2023.06.16
Matt Harbison <matt_harbison@yahoo.com>
parents: 51196
diff changeset
117 List,
460e80488cf0 typing: lock in correct changes from pytype 2023.04.11 -> 2023.06.16
Matt Harbison <matt_harbison@yahoo.com>
parents: 51196
diff changeset
118 )
460e80488cf0 typing: lock in correct changes from pytype 2023.04.11 -> 2023.06.16
Matt Harbison <matt_harbison@yahoo.com>
parents: 51196
diff changeset
119
43085
eef9a2d67051 py3: manually import pycompat.open into files that need it
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
120 from .pycompat import open
30583
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30573
diff changeset
121 from . import (
30642
344e68882cd3 py3: replace os.environ with encoding.environ (part 4 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30583
diff changeset
122 encoding,
30583
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30573
diff changeset
123 pycompat,
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30573
diff changeset
124 )
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30573
diff changeset
125
30270
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30269
diff changeset
126 defaultdict = collections.defaultdict
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30269
diff changeset
127 contextmanager = contextlib.contextmanager
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
128
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
129 __all__ = [b'start', b'stop', b'reset', b'display', b'profile']
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
130
40196
2864f8d3fcd6 py3: use raw strings for stack names
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40191
diff changeset
131 skips = {
43551
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43509
diff changeset
132 "util.py:check",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43509
diff changeset
133 "extensions.py:closure",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43509
diff changeset
134 "color.py:colorcmd",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43509
diff changeset
135 "dispatch.py:checkargs",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43509
diff changeset
136 "dispatch.py:<lambda>",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43509
diff changeset
137 "dispatch.py:_runcatch",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43509
diff changeset
138 "dispatch.py:_dispatch",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43509
diff changeset
139 "dispatch.py:_runcommand",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43509
diff changeset
140 "pager.py:pagecmd",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43509
diff changeset
141 "dispatch.py:run",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43509
diff changeset
142 "dispatch.py:dispatch",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43509
diff changeset
143 "dispatch.py:runcommand",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43509
diff changeset
144 "hg.py:<module>",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43509
diff changeset
145 "evolve.py:warnobserrors",
32331
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 31091
diff changeset
146 }
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
147
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
148 ###########################################################################
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
149 ## Utils
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
150
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
151
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
152 def clock():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
153 times = os.times()
38271
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38197
diff changeset
154 return (times[0] + times[1], times[4])
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
155
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
156
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
157 ###########################################################################
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
158 ## Collection data structures
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
159
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
160
49037
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 49030
diff changeset
161 class ProfileState:
51858
460e80488cf0 typing: lock in correct changes from pytype 2023.04.11 -> 2023.06.16
Matt Harbison <matt_harbison@yahoo.com>
parents: 51196
diff changeset
162 samples: List["Sample"]
460e80488cf0 typing: lock in correct changes from pytype 2023.04.11 -> 2023.06.16
Matt Harbison <matt_harbison@yahoo.com>
parents: 51196
diff changeset
163
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
164 def __init__(self, frequency=None):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
165 self.reset(frequency)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
166 self.track = b'cpu'
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
167
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
168 def reset(self, frequency=None):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
169 # total so far
38271
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38197
diff changeset
170 self.accumulated_time = (0.0, 0.0)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
171 # start_time when timer is active
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
172 self.last_start_time = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
173 # a float
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
174 if frequency:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
175 self.sample_interval = 1.0 / frequency
50952
18c8c18993f0 pycompat: drop usage of hasattr/getattr/setattr/delatt proxy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50305
diff changeset
176 elif not hasattr(self, 'sample_interval'):
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
177 # default to 1000 Hz
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
178 self.sample_interval = 1.0 / 1000.0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
179 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
180 # leave the frequency as it was
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
181 pass
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
182 self.remaining_prof_time = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
183 # for user start/stop nesting
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
184 self.profile_level = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
185
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
186 self.samples = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
187
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
188 def accumulate_time(self, stop_time):
38271
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38197
diff changeset
189 increment = (
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38197
diff changeset
190 stop_time[0] - self.last_start_time[0],
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38197
diff changeset
191 stop_time[1] - self.last_start_time[1],
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38197
diff changeset
192 )
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38197
diff changeset
193 self.accumulated_time = (
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38197
diff changeset
194 self.accumulated_time[0] + increment[0],
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38197
diff changeset
195 self.accumulated_time[1] + increment[1],
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38197
diff changeset
196 )
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
197
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
198 def seconds_per_sample(self):
38272
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38271
diff changeset
199 return self.accumulated_time[self.timeidx] / len(self.samples)
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38271
diff changeset
200
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38271
diff changeset
201 @property
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38271
diff changeset
202 def timeidx(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
203 if self.track == b'real':
38272
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38271
diff changeset
204 return 1
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38271
diff changeset
205 return 0
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
206
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
207
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
208 state = ProfileState()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
209
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
210
49037
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 49030
diff changeset
211 class CodeSite:
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
212 cache = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
213
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
214 __slots__ = ('path', 'lineno', 'function', 'source')
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
215
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
216 def __init__(self, path, lineno, function):
40534
93501a5fd62b statprof: add a couple of asserts to avoid storing unicodes
Augie Fackler <augie@google.com>
parents: 40385
diff changeset
217 assert isinstance(path, bytes)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
218 self.path = path
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
219 self.lineno = lineno
40534
93501a5fd62b statprof: add a couple of asserts to avoid storing unicodes
Augie Fackler <augie@google.com>
parents: 40385
diff changeset
220 assert isinstance(function, bytes)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
221 self.function = function
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
222 self.source = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
223
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
224 def __eq__(self, other):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
225 try:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
226 return self.lineno == other.lineno and self.path == other.path
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
227 except:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
228 return False
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
229
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
230 def __hash__(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
231 return hash((self.lineno, self.path))
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
232
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
233 @classmethod
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
234 def get(cls, path, lineno, function):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
235 k = (path, lineno)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
236 try:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
237 return cls.cache[k]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
238 except KeyError:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
239 v = cls(path, lineno, function)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
240 cls.cache[k] = v
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
241 return v
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
242
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
243 def getsource(self, length):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
244 if self.source is None:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
245 try:
49561
aab3d4c05720 profile: prevent a crash when line number is unknown
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49037
diff changeset
246 lineno = self.lineno - 1 # lineno can be None
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
247 with open(self.path, b'rb') as fp:
42844
c085cb134b9e statprof: use context manager when reading source from file
Martin von Zweigbergk <martinvonz@google.com>
parents: 42843
diff changeset
248 for i, line in enumerate(fp):
c085cb134b9e statprof: use context manager when reading source from file
Martin von Zweigbergk <martinvonz@google.com>
parents: 42843
diff changeset
249 if i == lineno:
c085cb134b9e statprof: use context manager when reading source from file
Martin von Zweigbergk <martinvonz@google.com>
parents: 42843
diff changeset
250 self.source = line.strip()
c085cb134b9e statprof: use context manager when reading source from file
Martin von Zweigbergk <martinvonz@google.com>
parents: 42843
diff changeset
251 break
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
252 except:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
253 pass
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
254 if self.source is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
255 self.source = b''
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
256
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
257 source = self.source
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
258 if len(source) > length:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
259 source = source[: (length - 3)] + b"..."
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
260 return source
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
261
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
262 def filename(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
263 return os.path.basename(self.path)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
264
40385
cc4586749c8c statprof: fix overflow while skipping boilerplate parts
Yuya Nishihara <yuya@tcha.org>
parents: 40384
diff changeset
265 def skipname(self):
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
266 return '%s:%s' % (self.filename(), self.function)
40385
cc4586749c8c statprof: fix overflow while skipping boilerplate parts
Yuya Nishihara <yuya@tcha.org>
parents: 40384
diff changeset
267
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
268
49037
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 49030
diff changeset
269 class Sample:
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
270 __slots__ = ('stack', 'time')
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
271
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
272 def __init__(self, stack, time):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
273 self.stack = stack
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
274 self.time = time
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
275
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
276 @classmethod
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
277 def from_frame(cls, frame, time):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
278 stack = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
279
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
280 while frame:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
281 stack.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
282 CodeSite.get(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
283 pycompat.sysbytes(frame.f_code.co_filename),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
284 frame.f_lineno,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
285 pycompat.sysbytes(frame.f_code.co_name),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
286 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
287 )
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
288 frame = frame.f_back
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
289
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
290 return Sample(stack, time)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
291
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
292
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
293 ###########################################################################
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
294 ## SIGPROF handler
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
295
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
296
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
297 def profile_signal_handler(signum, frame):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
298 if state.profile_level > 0:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
299 now = clock()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
300 state.accumulate_time(now)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
301
38272
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38271
diff changeset
302 timestamp = state.accumulated_time[state.timeidx]
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38271
diff changeset
303 state.samples.append(Sample.from_frame(frame, timestamp))
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
304
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
305 signal.setitimer(signal.ITIMER_PROF, state.sample_interval, 0.0)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
306 state.last_start_time = now
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
307
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
308
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
309 stopthread = threading.Event()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
310
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
311
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
312 def samplerthread(tid):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
313 while not stopthread.is_set():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
314 now = clock()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
315 state.accumulate_time(now)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
316
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
317 frame = sys._current_frames()[tid]
38272
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38271
diff changeset
318
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38271
diff changeset
319 timestamp = state.accumulated_time[state.timeidx]
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38271
diff changeset
320 state.samples.append(Sample.from_frame(frame, timestamp))
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
321
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
322 state.last_start_time = now
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
323 time.sleep(state.sample_interval)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
324
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
325 stopthread.clear()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
326
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
327
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
328 ###########################################################################
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
329 ## Profiling API
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
330
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
331
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
332 def is_active():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
333 return state.profile_level > 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
334
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
335
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
336 lastmechanism = None
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
337
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
338
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
339 def start(mechanism=b'thread', track=b'cpu'):
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
340 '''Install the profiling signal handler, and start profiling.'''
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
341 state.track = track # note: nesting different mode won't work
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
342 state.profile_level += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
343 if state.profile_level == 1:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
344 state.last_start_time = clock()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
345 rpt = state.remaining_prof_time
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
346 state.remaining_prof_time = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
347
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
348 global lastmechanism
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
349 lastmechanism = mechanism
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
350
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
351 if mechanism == b'signal':
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
352 signal.signal(signal.SIGPROF, profile_signal_handler)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
353 signal.setitimer(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
354 signal.ITIMER_PROF, rpt or state.sample_interval, 0.0
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
355 )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
356 elif mechanism == b'thread':
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
357 frame = inspect.currentframe()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
358 tid = [k for k, f in sys._current_frames().items() if f == frame][0]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
359 state.thread = threading.Thread(
43509
5c9daf7df2b4 statprof: correctly always pass a str as the thread name
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
360 target=samplerthread, args=(tid,), name="samplerthread"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
361 )
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
362 state.thread.start()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
363
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
364
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
365 def stop():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
366 '''Stop profiling, and uninstall the profiling signal handler.'''
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
367 state.profile_level -= 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
368 if state.profile_level == 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
369 if lastmechanism == b'signal':
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
370 rpt = signal.setitimer(signal.ITIMER_PROF, 0.0, 0.0)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
371 signal.signal(signal.SIGPROF, signal.SIG_IGN)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
372 state.remaining_prof_time = rpt[0]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
373 elif lastmechanism == b'thread':
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
374 stopthread.set()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
375 state.thread.join()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
376
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
377 state.accumulate_time(clock())
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
378 state.last_start_time = None
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
379 statprofpath = encoding.environ.get(b'STATPROF_DEST')
30269
f42cd5434cc2 statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30268
diff changeset
380 if statprofpath:
f42cd5434cc2 statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30268
diff changeset
381 save_data(statprofpath)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
382
30312
1e5346313963 statprof: return state from stop()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30272
diff changeset
383 return state
1e5346313963 statprof: return state from stop()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30272
diff changeset
384
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
385
30269
f42cd5434cc2 statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30268
diff changeset
386 def save_data(path):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
387 with open(path, b'w+') as file:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
388 file.write(b"%f %f\n" % state.accumulated_time)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
389 for sample in state.samples:
40197
113adb1b3f24 py3: use %d in a few places
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40196
diff changeset
390 time = sample.time
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
391 stack = sample.stack
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
392 sites = [
51196
933551630b0d statprof: handle `lineno == None` in more cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 50952
diff changeset
393 b'\1'.join([s.path, b'%d' % s.lineno or -1, s.function])
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
394 for s in stack
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
395 ]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
396 file.write(b"%d\0%s\n" % (time, b'\0'.join(sites)))
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
397
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
398
30269
f42cd5434cc2 statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30268
diff changeset
399 def load_data(path):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
400 lines = open(path, b'rb').read().splitlines()
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
401
38286
99188a7c8717 statprof: fix save and load
Boris Feld <boris.feld@octobus.net>
parents: 38272
diff changeset
402 state.accumulated_time = [float(value) for value in lines[0].split()]
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
403 state.samples = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
404 for line in lines[1:]:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
405 parts = line.split(b'\0')
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
406 time = float(parts[0])
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
407 rawsites = parts[1:]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
408 sites = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
409 for rawsite in rawsites:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
410 siteparts = rawsite.split(b'\1')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
411 sites.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
412 CodeSite.get(siteparts[0], int(siteparts[1]), siteparts[2])
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
413 )
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
414
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
415 state.samples.append(Sample(sites, time))
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
416
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
417
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
418 def reset(frequency=None):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43554
diff changeset
419 """Clear out the state of the profiler. Do not call while the
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
420 profiler is running.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
421
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
422 The optional frequency argument specifies the number of samples to
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43554
diff changeset
423 collect per second."""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
424 assert state.profile_level == 0, b"Can't reset() while statprof is running"
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
425 CodeSite.cache.clear()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
426 state.reset(frequency)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
427
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
428
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
429 @contextmanager
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
430 def profile():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
431 start()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
432 try:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
433 yield
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
434 finally:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
435 stop()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
436 display()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
437
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
438
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
439 ###########################################################################
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
440 ## Reporting API
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
441
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
442
49037
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 49030
diff changeset
443 class SiteStats:
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
444 def __init__(self, site):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
445 self.site = site
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
446 self.selfcount = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
447 self.totalcount = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
448
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
449 def addself(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
450 self.selfcount += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
451
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
452 def addtotal(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
453 self.totalcount += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
454
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
455 def selfpercent(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
456 return self.selfcount / len(state.samples) * 100
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
457
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
458 def totalpercent(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
459 return self.totalcount / len(state.samples) * 100
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
460
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
461 def selfseconds(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
462 return self.selfcount * state.seconds_per_sample()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
463
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
464 def totalseconds(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
465 return self.totalcount * state.seconds_per_sample()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
466
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
467 @classmethod
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
468 def buildstats(cls, samples):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
469 stats = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
470
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
471 for sample in samples:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
472 for i, site in enumerate(sample.stack):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
473 sitestat = stats.get(site)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
474 if not sitestat:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
475 sitestat = SiteStats(site)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
476 stats[site] = sitestat
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
477
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
478 sitestat.addtotal()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
479
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
480 if i == 0:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
481 sitestat.addself()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
482
49026
2cce2fa5bcf7 py3: replace pycompat.itervalues(x) with x.values()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 49004
diff changeset
483 return [s for s in stats.values()]
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
484
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
485
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
486 class DisplayFormats:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
487 ByLine = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
488 ByMethod = 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
489 AboutMethod = 2
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
490 Hotpath = 3
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
491 FlameGraph = 4
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
492 Json = 5
30949
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
493 Chrome = 6
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
494
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
495
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
496 def display(fp=None, format=3, data=None, **kwargs):
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
497 '''Print statistics, either to stdout or the given file object.'''
38697
3c569172848d statprof: small if cleanup
Boris Feld <boris.feld@octobus.net>
parents: 38286
diff changeset
498 if data is None:
3c569172848d statprof: small if cleanup
Boris Feld <boris.feld@octobus.net>
parents: 38286
diff changeset
499 data = state
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
500
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
501 if fp is None:
48521
d2fff292c265 pytype: stop excluding statprof.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 48520
diff changeset
502 from .utils import procutil
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
503
48521
d2fff292c265 pytype: stop excluding statprof.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 48520
diff changeset
504 fp = procutil.stdout
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
505 if len(data.samples) == 0:
40198
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
506 fp.write(b'No samples recorded.\n')
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
507 return
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
508
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
509 if format == DisplayFormats.ByLine:
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
510 display_by_line(data, fp)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
511 elif format == DisplayFormats.ByMethod:
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
512 display_by_method(data, fp)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
513 elif format == DisplayFormats.AboutMethod:
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
514 display_about_method(data, fp, **kwargs)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
515 elif format == DisplayFormats.Hotpath:
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
516 display_hotpath(data, fp, **kwargs)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
517 elif format == DisplayFormats.FlameGraph:
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
518 write_to_flame(data, fp, **kwargs)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
519 elif format == DisplayFormats.Json:
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
520 write_to_json(data, fp)
30949
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
521 elif format == DisplayFormats.Chrome:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
522 write_to_chrome(data, fp, **kwargs)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
523 else:
48520
c1fe758c1530 statprof: convert a few exception byte strings to str
Matt Harbison <matt_harbison@yahoo.com>
parents: 46033
diff changeset
524 raise Exception("Invalid display format")
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
525
30949
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
526 if format not in (DisplayFormats.Json, DisplayFormats.Chrome):
40198
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
527 fp.write(b'---\n')
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
528 fp.write(b'Sample count: %d\n' % len(data.samples))
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
529 fp.write(b'Total time: %f seconds (%f wall)\n' % data.accumulated_time)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
530
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
531
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
532 def display_by_line(data, fp):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43554
diff changeset
533 """Print the profiler data with each sample line represented
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43554
diff changeset
534 as one row in a table. Sorted by self-time per line."""
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
535 stats = SiteStats.buildstats(data.samples)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
536 stats.sort(reverse=True, key=lambda x: x.selfseconds())
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
537
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
538 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
539 b'%5.5s %10.10s %7.7s %-8.8s\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
540 % (b'% ', b'cumulative', b'self', b'')
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
541 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
542 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
543 b'%5.5s %9.9s %8.8s %-8.8s\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
544 % (b"time", b"seconds", b"seconds", b"name")
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
545 )
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
546
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
547 for stat in stats:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
548 site = stat.site
50305
972f3e5c94b8 statprof: with Python 3.12, lineno is (more) often None
Mads Kiilerich <mads@kiilerich.com>
parents: 49901
diff changeset
549 sitelabel = b'%s:%d:%s' % (
972f3e5c94b8 statprof: with Python 3.12, lineno is (more) often None
Mads Kiilerich <mads@kiilerich.com>
parents: 49901
diff changeset
550 site.filename(),
972f3e5c94b8 statprof: with Python 3.12, lineno is (more) often None
Mads Kiilerich <mads@kiilerich.com>
parents: 49901
diff changeset
551 site.lineno or -1,
972f3e5c94b8 statprof: with Python 3.12, lineno is (more) often None
Mads Kiilerich <mads@kiilerich.com>
parents: 49901
diff changeset
552 site.function,
972f3e5c94b8 statprof: with Python 3.12, lineno is (more) often None
Mads Kiilerich <mads@kiilerich.com>
parents: 49901
diff changeset
553 )
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
554 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
555 b'%6.2f %9.2f %9.2f %s\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
556 % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
557 stat.selfpercent(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
558 stat.totalseconds(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
559 stat.selfseconds(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
560 sitelabel,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
561 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
562 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
563
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
564
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
565 def display_by_method(data, fp):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43554
diff changeset
566 """Print the profiler data with each sample function represented
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
567 as one row in a table. Important lines within that function are
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43554
diff changeset
568 output as nested rows. Sorted by self-time per line."""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
569 fp.write(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
570 b'%5.5s %10.10s %7.7s %-8.8s\n'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
571 % (b'% ', b'cumulative', b'self', b'')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
572 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
573 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
574 b'%5.5s %9.9s %8.8s %-8.8s\n'
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
575 % (b"time", b"seconds", b"seconds", b"name")
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
576 )
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
577
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
578 stats = SiteStats.buildstats(data.samples)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
579
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
580 grouped = defaultdict(list)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
581 for stat in stats:
40535
8664fdc1cfb3 statprof: clean up unicode/bytes a little
Augie Fackler <augie@google.com>
parents: 40534
diff changeset
582 grouped[stat.site.filename() + b":" + stat.site.function].append(stat)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
583
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
584 # compute sums for each function
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
585 functiondata = []
49004
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48966
diff changeset
586 for fname, sitestats in grouped.items():
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
587 total_cum_sec = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
588 total_self_sec = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
589 total_percent = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
590 for stat in sitestats:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
591 total_cum_sec += stat.totalseconds()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
592 total_self_sec += stat.selfseconds()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
593 total_percent += stat.selfpercent()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
594
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
595 functiondata.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
596 (fname, total_cum_sec, total_self_sec, total_percent, sitestats)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
597 )
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
598
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
599 # sort by total self sec
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
600 functiondata.sort(reverse=True, key=lambda x: x[2])
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
601
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
602 for function in functiondata:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
603 if function[3] < 0.05:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
604 continue
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
605 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
606 b'%6.2f %9.2f %9.2f %s\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
607 % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
608 function[3], # total percent
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
609 function[1], # total cum sec
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
610 function[2], # total self sec
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
611 function[0],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
612 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
613 ) # file:function
40198
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
614
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
615 function[4].sort(reverse=True, key=lambda i: i.selfseconds())
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
616 for stat in function[4]:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
617 # only show line numbers for significant locations (>1% time spent)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
618 if stat.selfpercent() > 1:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
619 source = stat.site.getsource(25)
49030
37537a4d2695 statprof: remove superfluous sys.version_info check
Gregory Szorc <gregory.szorc@gmail.com>
parents: 49026
diff changeset
620 if not isinstance(source, bytes):
40201
7df42042636d py3: sprinkle statprof.py with utf-8 encoding
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40199
diff changeset
621 source = pycompat.bytestr(source)
7df42042636d py3: sprinkle statprof.py with utf-8 encoding
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40199
diff changeset
622
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
623 stattuple = (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
624 stat.selfpercent(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
625 stat.selfseconds(),
50305
972f3e5c94b8 statprof: with Python 3.12, lineno is (more) often None
Mads Kiilerich <mads@kiilerich.com>
parents: 49901
diff changeset
626 stat.site.lineno or -1,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
627 source,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
628 )
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
629
40198
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
630 fp.write(b'%33.0f%% %6.2f line %d: %s\n' % stattuple)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
631
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
632
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
633 def display_about_method(data, fp, function=None, **kwargs):
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
634 if function is None:
48520
c1fe758c1530 statprof: convert a few exception byte strings to str
Matt Harbison <matt_harbison@yahoo.com>
parents: 46033
diff changeset
635 raise Exception("Invalid function")
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
636
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
637 filename = None
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
638 if b':' in function:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
639 filename, function = function.split(b':')
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
640
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
641 relevant_samples = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
642 parents = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
643 children = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
644
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
645 for sample in data.samples:
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
646 for i, site in enumerate(sample.stack):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
647 if site.function == function and (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
648 not filename or site.filename() == filename
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
649 ):
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
650 relevant_samples += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
651 if i != len(sample.stack) - 1:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
652 parent = sample.stack[i + 1]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
653 if parent in parents:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
654 parents[parent] = parents[parent] + 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
655 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
656 parents[parent] = 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
657
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
658 if site in children:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
659 children[site] = children[site] + 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
660 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
661 children[site] = 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
662
49004
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48966
diff changeset
663 parents = [(parent, count) for parent, count in parents.items()]
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
664 parents.sort(reverse=True, key=lambda x: x[1])
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
665 for parent, count in parents:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
666 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
667 b'%6.2f%% %s:%s line %s: %s\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
668 % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
669 count / relevant_samples * 100,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
670 pycompat.fsencode(parent.filename()),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
671 pycompat.sysbytes(parent.function),
51196
933551630b0d statprof: handle `lineno == None` in more cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 50952
diff changeset
672 parent.lineno or -1,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
673 pycompat.sysbytes(parent.getsource(50)),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
674 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
675 )
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
676
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
677 stats = SiteStats.buildstats(data.samples)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
678 stats = [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
679 s
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
680 for s in stats
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
681 if s.site.function == function
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
682 and (not filename or s.site.filename() == filename)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
683 ]
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
684
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
685 total_cum_sec = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
686 total_self_sec = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
687 total_self_percent = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
688 total_cum_percent = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
689 for stat in stats:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
690 total_cum_sec += stat.totalseconds()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
691 total_self_sec += stat.selfseconds()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
692 total_self_percent += stat.selfpercent()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
693 total_cum_percent += stat.totalpercent()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
694
40198
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
695 fp.write(
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
696 b'\n %s:%s Total: %0.2fs (%0.2f%%) Self: %0.2fs (%0.2f%%)\n\n'
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
697 % (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
698 pycompat.sysbytes(filename or b'___'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
699 pycompat.sysbytes(function),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
700 total_cum_sec,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
701 total_cum_percent,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
702 total_self_sec,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
703 total_self_percent,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
704 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
705 )
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
706
49004
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48966
diff changeset
707 children = [(child, count) for child, count in children.items()]
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
708 children.sort(reverse=True, key=lambda x: x[1])
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
709 for child, count in children:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
710 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
711 b' %6.2f%% line %s: %s\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
712 % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
713 count / relevant_samples * 100,
51196
933551630b0d statprof: handle `lineno == None` in more cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 50952
diff changeset
714 child.lineno or -1,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
715 pycompat.sysbytes(child.getsource(50)),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
716 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
717 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
718
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
719
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
720 def display_hotpath(data, fp, limit=0.05, **kwargs):
49037
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 49030
diff changeset
721 class HotNode:
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
722 def __init__(self, site):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
723 self.site = site
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
724 self.count = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
725 self.children = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
726
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
727 def add(self, stack, time):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
728 self.count += time
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
729 site = stack[0]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
730 child = self.children.get(site)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
731 if not child:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
732 child = HotNode(site)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
733 self.children[site] = child
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
734
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
735 if len(stack) > 1:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
736 i = 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
737 # Skip boiler plate parts of the stack
40385
cc4586749c8c statprof: fix overflow while skipping boilerplate parts
Yuya Nishihara <yuya@tcha.org>
parents: 40384
diff changeset
738 while i < len(stack) and stack[i].skipname() in skips:
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
739 i += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
740 if i < len(stack):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
741 child.add(stack[i:], time)
46032
068307b638f4 statprof: fix off-by-one-line error in output
Kyle Lippincott <spectral@google.com>
parents: 45957
diff changeset
742 else:
068307b638f4 statprof: fix off-by-one-line error in output
Kyle Lippincott <spectral@google.com>
parents: 45957
diff changeset
743 # Normally this is done by the .add() calls
068307b638f4 statprof: fix off-by-one-line error in output
Kyle Lippincott <spectral@google.com>
parents: 45957
diff changeset
744 child.count += time
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
745
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
746 root = HotNode(None)
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
747 lasttime = data.samples[0].time
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
748 for sample in data.samples:
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
749 root.add(sample.stack[::-1], sample.time - lasttime)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
750 lasttime = sample.time
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
751 showtime = kwargs.get('showtime', True)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
752
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
753 def _write(node, depth, multiple_siblings):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
754 site = node.site
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
755 visiblechildren = [
49026
2cce2fa5bcf7 py3: replace pycompat.itervalues(x) with x.values()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 49004
diff changeset
756 c for c in node.children.values() if c.count >= (limit * root.count)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
757 ]
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
758 if site:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
759 indent = depth * 2 - 1
46032
068307b638f4 statprof: fix off-by-one-line error in output
Kyle Lippincott <spectral@google.com>
parents: 45957
diff changeset
760 filename = (site.filename() + b':').ljust(15)
068307b638f4 statprof: fix off-by-one-line error in output
Kyle Lippincott <spectral@google.com>
parents: 45957
diff changeset
761 function = site.function
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
762
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
763 # lots of string formatting
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
764 listpattern = (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
765 b''.ljust(indent)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
766 + (b'\\' if multiple_siblings else b'|')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
767 + b' %4.1f%%'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
768 + (b' %5.2fs' % node.count if showtime else b'')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
769 + b' %s %s'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
770 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
771 liststring = listpattern % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
772 node.count / root.count * 100,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
773 filename,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
774 function,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
775 )
46033
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46032
diff changeset
776 # 4 to account for the word 'line'
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46032
diff changeset
777 spacing_len = max(4, 55 - len(liststring))
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46032
diff changeset
778 prefix = b''
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46032
diff changeset
779 if spacing_len == 4:
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46032
diff changeset
780 prefix = b', '
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46032
diff changeset
781
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46032
diff changeset
782 codepattern = b'%s%s %d: %s%s'
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
783 codestring = codepattern % (
46033
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46032
diff changeset
784 prefix,
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46032
diff changeset
785 b'line'.rjust(spacing_len),
49561
aab3d4c05720 profile: prevent a crash when line number is unknown
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49037
diff changeset
786 site.lineno if site.lineno is not None else -1,
46033
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46032
diff changeset
787 b''.ljust(max(0, 4 - len(str(site.lineno)))),
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
788 site.getsource(30),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
789 )
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
790
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
791 finalstring = liststring + codestring
49026
2cce2fa5bcf7 py3: replace pycompat.itervalues(x) with x.values()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 49004
diff changeset
792 childrensamples = sum([c.count for c in node.children.values()])
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
793 # Make frames that performed more than 10% of the operation red
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
794 if node.count - childrensamples > (0.1 * root.count):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
795 finalstring = b'\033[91m' + finalstring + b'\033[0m'
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
796 # Make frames that didn't actually perform work dark grey
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
797 elif node.count - childrensamples == 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
798 finalstring = b'\033[90m' + finalstring + b'\033[0m'
40384
fc4c598dd4a0 statprof: fix indent level of fp.write() (issue6004)
Yuya Nishihara <yuya@tcha.org>
parents: 40381
diff changeset
799 fp.write(finalstring + b'\n')
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
800
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
801 newdepth = depth
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
802 if len(visiblechildren) > 1 or multiple_siblings:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
803 newdepth += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
804
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
805 visiblechildren.sort(reverse=True, key=lambda x: x.count)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
806 for child in visiblechildren:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
807 _write(child, newdepth, len(visiblechildren) > 1)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
808
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
809 if root.count > 0:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
810 _write(root, 0, False)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
811
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
812
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
813 def write_to_flame(data, fp, scriptpath=None, outputfile=None, **kwargs):
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
814 if scriptpath is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
815 scriptpath = encoding.environ[b'HOME'] + b'/flamegraph.pl'
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
816 if not os.path.exists(scriptpath):
40198
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
817 fp.write(b'error: missing %s\n' % scriptpath)
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
818 fp.write(b'get it here: https://github.com/brendangregg/FlameGraph\n')
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
819 return
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
820
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
821 lines = {}
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
822 for sample in data.samples:
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
823 sites = [s.function for s in sample.stack]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
824 sites.reverse()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
825 line = b';'.join(sites)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
826 if line in lines:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
827 lines[line] = lines[line] + 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
828 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
829 lines[line] = 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
830
42845
db6d7cbda80b statprof: use context manager for file when writing flame graph
Martin von Zweigbergk <martinvonz@google.com>
parents: 42844
diff changeset
831 fd, path = pycompat.mkstemp()
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
832
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
833 with open(path, b"w+") as file:
49004
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48966
diff changeset
834 for line, count in lines.items():
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
835 file.write(b"%s %d\n" % (line, count))
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
836
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
837 if outputfile is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
838 outputfile = b'~/flamegraph.svg'
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
839
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
840 os.system(b"perl ~/flamegraph.pl %s > %s" % (path, outputfile))
40198
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
841 fp.write(b'Written to %s\n' % outputfile)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
842
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
843
30948
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
844 _pathcache = {}
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
845
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
846
30948
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
847 def simplifypath(path):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43554
diff changeset
848 """Attempt to make the path to a Python module easier to read by
30948
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
849 removing whatever part of the Python search path it was found
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43554
diff changeset
850 on."""
30948
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
851
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
852 if path in _pathcache:
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
853 return _pathcache[path]
42847
cde1c101ab8a py3: make statprof's chrome output work
Martin von Zweigbergk <martinvonz@google.com>
parents: 42846
diff changeset
854 hgpath = encoding.__file__.rsplit(os.sep, 2)[0]
30948
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
855 for p in [hgpath] + sys.path:
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
856 prefix = p + os.sep
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
857 if path.startswith(prefix):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
858 path = path[len(prefix) :]
30948
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
859 break
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
860 _pathcache[path] = path
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
861 return path
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
862
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
863
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
864 def write_to_json(data, fp):
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
865 samples = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
866
30272
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30271
diff changeset
867 for sample in data.samples:
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
868 stack = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
869
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
870 for frame in sample.stack:
40535
8664fdc1cfb3 statprof: clean up unicode/bytes a little
Augie Fackler <augie@google.com>
parents: 40534
diff changeset
871 stack.append(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
872 (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
873 pycompat.sysstr(frame.path),
51196
933551630b0d statprof: handle `lineno == None` in more cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 50952
diff changeset
874 frame.lineno or -1,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
875 pycompat.sysstr(frame.function),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
876 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
877 )
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
878
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
879 samples.append((sample.time, stack))
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
880
40191
4b7eb862692e py3: encode json output to bytes and use write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39129
diff changeset
881 data = json.dumps(samples)
4b7eb862692e py3: encode json output to bytes and use write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39129
diff changeset
882 if not isinstance(data, bytes):
4b7eb862692e py3: encode json output to bytes and use write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39129
diff changeset
883 data = data.encode('utf-8')
4b7eb862692e py3: encode json output to bytes and use write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39129
diff changeset
884
4b7eb862692e py3: encode json output to bytes and use write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39129
diff changeset
885 fp.write(data)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
886
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
887
30949
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
888 def write_to_chrome(data, fp, minthreshold=0.005, maxthreshold=0.999):
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
889 samples = []
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
890 laststack = collections.deque()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
891 lastseen = collections.deque()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
892
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
893 # The Chrome tracing format allows us to use a compact stack
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
894 # representation to save space. It's fiddly but worth it.
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
895 # We maintain a bijection between stack and ID.
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
896 stack2id = {}
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
897 id2stack = [] # will eventually be rendered
30949
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
898
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
899 def stackid(stack):
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
900 if not stack:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
901 return
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
902 if stack in stack2id:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
903 return stack2id[stack]
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
904 parent = stackid(stack[1:])
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
905 myid = len(stack2id)
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
906 stack2id[stack] = myid
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
907 id2stack.append(dict(category=stack[0][0], name='%s %s' % stack[0]))
30949
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
908 if parent is not None:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
909 id2stack[-1].update(parent=parent)
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
910 return myid
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
911
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
912 # The sampling profiler can sample multiple times without
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
913 # advancing the clock, potentially causing the Chrome trace viewer
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
914 # to render single-pixel columns that we cannot zoom in on. We
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
915 # work around this by pretending that zero-duration samples are a
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
916 # millisecond in length.
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
917
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
918 clamp = 0.001
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
919
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
920 # We provide knobs that by default attempt to filter out stack
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
921 # frames that are too noisy:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
922 #
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
923 # * A few take almost all execution time. These are usually boring
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
924 # setup functions, giving a stack that is deep but uninformative.
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
925 #
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
926 # * Numerous samples take almost no time, but introduce lots of
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
927 # noisy, oft-deep "spines" into a rendered profile.
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
928
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
929 blacklist = set()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
930 totaltime = data.samples[-1].time - data.samples[0].time
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
931 minthreshold = totaltime * minthreshold
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
932 maxthreshold = max(totaltime * maxthreshold, clamp)
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
933
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
934 def poplast():
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
935 oldsid = stackid(tuple(laststack))
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
936 oldcat, oldfunc = laststack.popleft()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
937 oldtime, oldidx = lastseen.popleft()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
938 duration = sample.time - oldtime
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
939 if minthreshold <= duration <= maxthreshold:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
940 # ensure no zero-duration events
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
941 sampletime = max(oldtime + clamp, sample.time)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
942 samples.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
943 dict(
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
944 ph='E',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
945 name=oldfunc,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
946 cat=oldcat,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
947 sf=oldsid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
948 ts=sampletime * 1e6,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
949 pid=0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
950 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
951 )
30949
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
952 else:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
953 blacklist.add(oldidx)
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
954
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
955 # Much fiddling to synthesize correctly(ish) nested begin/end
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
956 # events given only stack snapshots.
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
957
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
958 for sample in data.samples:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
959 stack = tuple(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
960 (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
961 (
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
962 '%s:%d'
51196
933551630b0d statprof: handle `lineno == None` in more cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 50952
diff changeset
963 % (
933551630b0d statprof: handle `lineno == None` in more cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 50952
diff changeset
964 simplifypath(pycompat.sysstr(frame.path)),
933551630b0d statprof: handle `lineno == None` in more cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 50952
diff changeset
965 frame.lineno or -1,
933551630b0d statprof: handle `lineno == None` in more cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 50952
diff changeset
966 ),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
967 pycompat.sysstr(frame.function),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
968 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
969 for frame in sample.stack
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
970 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
971 )
30949
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
972 qstack = collections.deque(stack)
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
973 if laststack == qstack:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
974 continue
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
975 while laststack and qstack and laststack[-1] == qstack[-1]:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
976 laststack.pop()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
977 qstack.pop()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
978 while laststack:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
979 poplast()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
980 for f in reversed(qstack):
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
981 lastseen.appendleft((sample.time, len(samples)))
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
982 laststack.appendleft(f)
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
983 path, name = f
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
984 sid = stackid(tuple(laststack))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
985 samples.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
986 dict(
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
987 ph='B',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
988 name=name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
989 cat=path,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
990 ts=sample.time * 1e6,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
991 sf=sid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
992 pid=0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
993 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
994 )
30949
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
995 laststack = collections.deque(stack)
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
996 while laststack:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
997 poplast()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
998 events = [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
999 sample for idx, sample in enumerate(samples) if idx not in blacklist
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1000 ]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1001 frames = collections.OrderedDict(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1002 (str(k), v) for (k, v) in enumerate(id2stack)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1003 )
42846
cd3b5be5515d py3: for statprof's Chrome output, write json to string, then encode to bytes
Martin von Zweigbergk <martinvonz@google.com>
parents: 42845
diff changeset
1004 data = json.dumps(dict(traceEvents=events, stackFrames=frames), indent=1)
cd3b5be5515d py3: for statprof's Chrome output, write json to string, then encode to bytes
Martin von Zweigbergk <martinvonz@google.com>
parents: 42845
diff changeset
1005 if not isinstance(data, bytes):
cd3b5be5515d py3: for statprof's Chrome output, write json to string, then encode to bytes
Martin von Zweigbergk <martinvonz@google.com>
parents: 42845
diff changeset
1006 data = data.encode('utf-8')
cd3b5be5515d py3: for statprof's Chrome output, write json to string, then encode to bytes
Martin von Zweigbergk <martinvonz@google.com>
parents: 42845
diff changeset
1007 fp.write(data)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1008 fp.write(b'\n')
30949
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30948
diff changeset
1009
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1010
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1011 def printusage():
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1012 print(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1013 r"""
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1014 The statprof command line allows you to inspect the last profile's results in
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1015 the following forms:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1016
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1017 usage:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1018 hotpath [-l --limit percent]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1019 Shows a graph of calls with the percent of time each takes.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1020 Red calls take over 10%% of the total time themselves.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1021 lines
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1022 Shows the actual sampled lines.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1023 functions
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1024 Shows the samples grouped by function.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1025 function [filename:]functionname
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1026 Shows the callers and callees of a particular function.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1027 flame [-s --script-path] [-o --output-file path]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1028 Writes out a flamegraph to output-file (defaults to ~/flamegraph.svg)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1029 Requires that ~/flamegraph.pl exist.
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1030 (Specify alternate script path with --script-path.)"""
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1031 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1032
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1033
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1034 def main(argv=None):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1035 if argv is None:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1036 argv = sys.argv
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1037
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1038 if len(argv) == 1:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1039 printusage()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1040 return 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1041
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1042 displayargs = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1043
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1044 optstart = 2
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1045 displayargs[b'function'] = None
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
1046 if argv[1] == 'hotpath':
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1047 displayargs[b'format'] = DisplayFormats.Hotpath
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
1048 elif argv[1] == 'lines':
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1049 displayargs[b'format'] = DisplayFormats.ByLine
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
1050 elif argv[1] == 'functions':
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1051 displayargs[b'format'] = DisplayFormats.ByMethod
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
1052 elif argv[1] == 'function':
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1053 displayargs[b'format'] = DisplayFormats.AboutMethod
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1054 displayargs[b'function'] = argv[2]
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1055 optstart = 3
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
1056 elif argv[1] == 'flame':
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1057 displayargs[b'format'] = DisplayFormats.FlameGraph
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1058 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1059 printusage()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1060 return 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1061
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1062 # process options
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1063 try:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1064 opts, args = pycompat.getoptb(
49901
9eb69fa5a783 statprof: don't pass str `sys.argv` to a function expecting bytes
Matt Harbison <matt_harbison@yahoo.com>
parents: 49561
diff changeset
1065 pycompat.sysargv[optstart:],
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1066 b"hl:f:o:p:",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1067 [b"help", b"limit=", b"file=", b"output-file=", b"script-path="],
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1068 )
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1069 except getopt.error as msg:
30271
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30270
diff changeset
1070 print(msg)
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1071 printusage()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1072 return 2
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1073
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1074 displayargs[b'limit'] = 0.05
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1075 path = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1076 for o, value in opts:
43551
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43509
diff changeset
1077 if o in ("-l", "--limit"):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1078 displayargs[b'limit'] = float(value)
43551
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43509
diff changeset
1079 elif o in ("-f", "--file"):
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1080 path = value
43551
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43509
diff changeset
1081 elif o in ("-o", "--output-file"):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1082 displayargs[b'outputfile'] = value
43551
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43509
diff changeset
1083 elif o in ("-p", "--script-path"):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1084 displayargs[b'scriptpath'] = value
43551
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43509
diff changeset
1085 elif o in ("-h", "help"):
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1086 printusage()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1087 return 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1088 else:
48520
c1fe758c1530 statprof: convert a few exception byte strings to str
Matt Harbison <matt_harbison@yahoo.com>
parents: 46033
diff changeset
1089 assert False, "unhandled option %s" % o
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1090
30845
262c2be8ea5a statprof: require input file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30642
diff changeset
1091 if not path:
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
1092 print('must specify --file to load')
30845
262c2be8ea5a statprof: require input file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30642
diff changeset
1093 return 1
262c2be8ea5a statprof: require input file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30642
diff changeset
1094
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1095 load_data(path=path)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1096
35379
c5853c9a6545 py3: handle keyword arguments correctly in statprof.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32331
diff changeset
1097 display(**pycompat.strkwargs(displayargs))
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1098
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1099 return 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1100
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1101
43551
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43509
diff changeset
1102 if __name__ == "__main__":
30267
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1103 sys.exit(main())