annotate mercurial/statprof.py @ 51232:3551f2a1c963

debugindexstats: handle the lack of Rust support better We don't have any stats in the Rust index. Currently it is not known which stats would be interesting to get, so if they end up being important, we can add them later.
author Raphaël Gomès <rgomes@octobus.net>
date Tue, 31 Oct 2023 18:09:43 +0100
parents 933551630b0d
children 99632adff795 460e80488cf0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
30253
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
30256
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
105 import collections
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
106 import contextlib
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
107 import getopt
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
108 import inspect
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
109 import json
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
110 import os
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
111 import signal
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
112 import sys
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
113 import threading
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
114 import time
30256
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
115
43085
eef9a2d67051 py3: manually import pycompat.open into files that need it
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
116 from .pycompat import open
30578
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30568
diff changeset
117 from . import (
30637
344e68882cd3 py3: replace os.environ with encoding.environ (part 4 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30578
diff changeset
118 encoding,
30578
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30568
diff changeset
119 pycompat,
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30568
diff changeset
120 )
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30568
diff changeset
121
30256
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
122 defaultdict = collections.defaultdict
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
123 contextmanager = contextlib.contextmanager
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
124
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
125 __all__ = [b'start', b'stop', b'reset', b'display', b'profile']
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
126
40196
2864f8d3fcd6 py3: use raw strings for stack names
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40191
diff changeset
127 skips = {
43503
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
128 "util.py:check",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
129 "extensions.py:closure",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
130 "color.py:colorcmd",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
131 "dispatch.py:checkargs",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
132 "dispatch.py:<lambda>",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
133 "dispatch.py:_runcatch",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
134 "dispatch.py:_dispatch",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
135 "dispatch.py:_runcommand",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
136 "pager.py:pagecmd",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
137 "dispatch.py:run",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
138 "dispatch.py:dispatch",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
139 "dispatch.py:runcommand",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
140 "hg.py:<module>",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
141 "evolve.py:warnobserrors",
32291
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 31074
diff changeset
142 }
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
143
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
144 ###########################################################################
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
145 ## Utils
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
146
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
147
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
148 def clock():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
149 times = os.times()
38259
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38164
diff changeset
150 return (times[0] + times[1], times[4])
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
151
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
152
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
153 ###########################################################################
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
154 ## Collection data structures
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
155
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
156
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48939
diff changeset
157 class ProfileState:
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
158 def __init__(self, frequency=None):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
159 self.reset(frequency)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
160 self.track = b'cpu'
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
161
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
162 def reset(self, frequency=None):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
163 # total so far
38259
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38164
diff changeset
164 self.accumulated_time = (0.0, 0.0)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
165 # start_time when timer is active
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
166 self.last_start_time = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
167 # a float
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
168 if frequency:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
169 self.sample_interval = 1.0 / frequency
50929
18c8c18993f0 pycompat: drop usage of hasattr/getattr/setattr/delatt proxy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50305
diff changeset
170 elif not hasattr(self, 'sample_interval'):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
171 # default to 1000 Hz
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
172 self.sample_interval = 1.0 / 1000.0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
173 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
174 # leave the frequency as it was
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
175 pass
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
176 self.remaining_prof_time = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
177 # for user start/stop nesting
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
178 self.profile_level = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
179
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
180 self.samples = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
181
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
182 def accumulate_time(self, stop_time):
38259
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38164
diff changeset
183 increment = (
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38164
diff changeset
184 stop_time[0] - self.last_start_time[0],
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38164
diff changeset
185 stop_time[1] - self.last_start_time[1],
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38164
diff changeset
186 )
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38164
diff changeset
187 self.accumulated_time = (
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38164
diff changeset
188 self.accumulated_time[0] + increment[0],
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38164
diff changeset
189 self.accumulated_time[1] + increment[1],
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38164
diff changeset
190 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
191
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
192 def seconds_per_sample(self):
38260
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
193 return self.accumulated_time[self.timeidx] / len(self.samples)
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
194
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
195 @property
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
196 def timeidx(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
197 if self.track == b'real':
38260
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
198 return 1
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
199 return 0
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
200
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
201
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
202 state = ProfileState()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
203
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
204
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48939
diff changeset
205 class CodeSite:
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
206 cache = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
207
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
208 __slots__ = ('path', 'lineno', 'function', 'source')
30253
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 def __init__(self, path, lineno, function):
40484
93501a5fd62b statprof: add a couple of asserts to avoid storing unicodes
Augie Fackler <augie@google.com>
parents: 40385
diff changeset
211 assert isinstance(path, bytes)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
212 self.path = path
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
213 self.lineno = lineno
40484
93501a5fd62b statprof: add a couple of asserts to avoid storing unicodes
Augie Fackler <augie@google.com>
parents: 40385
diff changeset
214 assert isinstance(function, bytes)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
215 self.function = function
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
216 self.source = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
217
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
218 def __eq__(self, other):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
219 try:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
220 return self.lineno == other.lineno and self.path == other.path
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
221 except:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
222 return False
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 __hash__(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
225 return hash((self.lineno, self.path))
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
226
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
227 @classmethod
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
228 def get(cls, path, lineno, function):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
229 k = (path, lineno)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
230 try:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
231 return cls.cache[k]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
232 except KeyError:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
233 v = cls(path, lineno, function)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
234 cls.cache[k] = v
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
235 return v
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
236
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
237 def getsource(self, length):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
238 if self.source is None:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
239 try:
49578
aab3d4c05720 profile: prevent a crash when line number is unknown
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
240 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
241 with open(self.path, b'rb') as fp:
42834
c085cb134b9e statprof: use context manager when reading source from file
Martin von Zweigbergk <martinvonz@google.com>
parents: 42833
diff changeset
242 for i, line in enumerate(fp):
c085cb134b9e statprof: use context manager when reading source from file
Martin von Zweigbergk <martinvonz@google.com>
parents: 42833
diff changeset
243 if i == lineno:
c085cb134b9e statprof: use context manager when reading source from file
Martin von Zweigbergk <martinvonz@google.com>
parents: 42833
diff changeset
244 self.source = line.strip()
c085cb134b9e statprof: use context manager when reading source from file
Martin von Zweigbergk <martinvonz@google.com>
parents: 42833
diff changeset
245 break
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
246 except:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
247 pass
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
248 if self.source is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
249 self.source = b''
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
250
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
251 source = self.source
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
252 if len(source) > length:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
253 source = source[: (length - 3)] + b"..."
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
254 return source
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
255
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
256 def filename(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
257 return os.path.basename(self.path)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
258
40385
cc4586749c8c statprof: fix overflow while skipping boilerplate parts
Yuya Nishihara <yuya@tcha.org>
parents: 40384
diff changeset
259 def skipname(self):
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
260 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
261
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
262
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48939
diff changeset
263 class Sample:
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
264 __slots__ = ('stack', 'time')
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
265
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
266 def __init__(self, stack, time):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
267 self.stack = stack
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
268 self.time = time
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
269
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
270 @classmethod
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
271 def from_frame(cls, frame, time):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
272 stack = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
273
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
274 while frame:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
275 stack.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
276 CodeSite.get(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
277 pycompat.sysbytes(frame.f_code.co_filename),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
278 frame.f_lineno,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
279 pycompat.sysbytes(frame.f_code.co_name),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
280 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
281 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
282 frame = frame.f_back
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
283
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
284 return Sample(stack, time)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
285
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
286
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
287 ###########################################################################
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
288 ## SIGPROF handler
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
289
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
290
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
291 def profile_signal_handler(signum, frame):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
292 if state.profile_level > 0:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
293 now = clock()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
294 state.accumulate_time(now)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
295
38260
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
296 timestamp = state.accumulated_time[state.timeidx]
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
297 state.samples.append(Sample.from_frame(frame, timestamp))
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
298
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
299 signal.setitimer(signal.ITIMER_PROF, state.sample_interval, 0.0)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
300 state.last_start_time = now
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
301
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
302
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
303 stopthread = threading.Event()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
304
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
305
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
306 def samplerthread(tid):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
307 while not stopthread.is_set():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
308 now = clock()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
309 state.accumulate_time(now)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
310
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
311 frame = sys._current_frames()[tid]
38260
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
312
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
313 timestamp = state.accumulated_time[state.timeidx]
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
314 state.samples.append(Sample.from_frame(frame, timestamp))
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
315
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
316 state.last_start_time = now
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
317 time.sleep(state.sample_interval)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
318
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
319 stopthread.clear()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
320
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
321
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
322 ###########################################################################
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
323 ## Profiling API
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
324
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
325
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
326 def is_active():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
327 return state.profile_level > 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
328
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
329
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
330 lastmechanism = None
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
331
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
332
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
333 def start(mechanism=b'thread', track=b'cpu'):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
334 '''Install the profiling signal handler, and start profiling.'''
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
335 state.track = track # note: nesting different mode won't work
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
336 state.profile_level += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
337 if state.profile_level == 1:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
338 state.last_start_time = clock()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
339 rpt = state.remaining_prof_time
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
340 state.remaining_prof_time = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
341
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
342 global lastmechanism
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
343 lastmechanism = mechanism
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
344
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
345 if mechanism == b'signal':
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
346 signal.signal(signal.SIGPROF, profile_signal_handler)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
347 signal.setitimer(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
348 signal.ITIMER_PROF, rpt or state.sample_interval, 0.0
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
349 )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
350 elif mechanism == b'thread':
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
351 frame = inspect.currentframe()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
352 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
353 state.thread = threading.Thread(
43461
5c9daf7df2b4 statprof: correctly always pass a str as the thread name
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
354 target=samplerthread, args=(tid,), name="samplerthread"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
355 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
356 state.thread.start()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
357
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
358
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
359 def stop():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
360 '''Stop profiling, and uninstall the profiling signal handler.'''
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
361 state.profile_level -= 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
362 if state.profile_level == 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
363 if lastmechanism == b'signal':
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
364 rpt = signal.setitimer(signal.ITIMER_PROF, 0.0, 0.0)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
365 signal.signal(signal.SIGPROF, signal.SIG_IGN)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
366 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
367 elif lastmechanism == b'thread':
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
368 stopthread.set()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
369 state.thread.join()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
370
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
371 state.accumulate_time(clock())
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
372 state.last_start_time = None
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
373 statprofpath = encoding.environ.get(b'STATPROF_DEST')
30255
f42cd5434cc2 statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30254
diff changeset
374 if statprofpath:
f42cd5434cc2 statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30254
diff changeset
375 save_data(statprofpath)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
376
30299
1e5346313963 statprof: return state from stop()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30258
diff changeset
377 return state
1e5346313963 statprof: return state from stop()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30258
diff changeset
378
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
379
30255
f42cd5434cc2 statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30254
diff changeset
380 def save_data(path):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
381 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
382 file.write(b"%f %f\n" % state.accumulated_time)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
383 for sample in state.samples:
40197
113adb1b3f24 py3: use %d in a few places
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40196
diff changeset
384 time = sample.time
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
385 stack = sample.stack
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
386 sites = [
51173
933551630b0d statprof: handle `lineno == None` in more cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 50929
diff changeset
387 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
388 for s in stack
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
389 ]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
390 file.write(b"%d\0%s\n" % (time, b'\0'.join(sites)))
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
391
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
392
30255
f42cd5434cc2 statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30254
diff changeset
393 def load_data(path):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
394 lines = open(path, b'rb').read().splitlines()
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
395
38274
99188a7c8717 statprof: fix save and load
Boris Feld <boris.feld@octobus.net>
parents: 38260
diff changeset
396 state.accumulated_time = [float(value) for value in lines[0].split()]
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
397 state.samples = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
398 for line in lines[1:]:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
399 parts = line.split(b'\0')
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
400 time = float(parts[0])
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
401 rawsites = parts[1:]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
402 sites = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
403 for rawsite in rawsites:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
404 siteparts = rawsite.split(b'\1')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
405 sites.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
406 CodeSite.get(siteparts[0], int(siteparts[1]), siteparts[2])
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
407 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
408
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
409 state.samples.append(Sample(sites, time))
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
410
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
411
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
412 def reset(frequency=None):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
413 """Clear out the state of the profiler. Do not call while the
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
414 profiler is running.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
415
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
416 The optional frequency argument specifies the number of samples to
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
417 collect per second."""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
418 assert state.profile_level == 0, b"Can't reset() while statprof is running"
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
419 CodeSite.cache.clear()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
420 state.reset(frequency)
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
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
423 @contextmanager
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
424 def profile():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
425 start()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
426 try:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
427 yield
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
428 finally:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
429 stop()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
430 display()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
431
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
432
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
433 ###########################################################################
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
434 ## Reporting API
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
435
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
436
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48939
diff changeset
437 class SiteStats:
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
438 def __init__(self, site):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
439 self.site = site
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
440 self.selfcount = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
441 self.totalcount = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
442
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
443 def addself(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
444 self.selfcount += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
445
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
446 def addtotal(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
447 self.totalcount += 1
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 selfpercent(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
450 return self.selfcount / len(state.samples) * 100
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 totalpercent(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
453 return self.totalcount / len(state.samples) * 100
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 selfseconds(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
456 return self.selfcount * state.seconds_per_sample()
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 totalseconds(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
459 return self.totalcount * state.seconds_per_sample()
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 @classmethod
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
462 def buildstats(cls, samples):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
463 stats = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
464
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
465 for sample in samples:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
466 for i, site in enumerate(sample.stack):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
467 sitestat = stats.get(site)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
468 if not sitestat:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
469 sitestat = SiteStats(site)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
470 stats[site] = sitestat
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
471
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
472 sitestat.addtotal()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
473
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
474 if i == 0:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
475 sitestat.addself()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
476
48935
2cce2fa5bcf7 py3: replace pycompat.itervalues(x) with x.values()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
477 return [s for s in stats.values()]
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
478
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
479
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
480 class DisplayFormats:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
481 ByLine = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
482 ByMethod = 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
483 AboutMethod = 2
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
484 Hotpath = 3
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
485 FlameGraph = 4
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
486 Json = 5
30929
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
487 Chrome = 6
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
488
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
489
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
490 def display(fp=None, format=3, data=None, **kwargs):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
491 '''Print statistics, either to stdout or the given file object.'''
38697
3c569172848d statprof: small if cleanup
Boris Feld <boris.feld@octobus.net>
parents: 38274
diff changeset
492 if data is None:
3c569172848d statprof: small if cleanup
Boris Feld <boris.feld@octobus.net>
parents: 38274
diff changeset
493 data = state
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
494
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
495 if fp is None:
48482
d2fff292c265 pytype: stop excluding statprof.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 48481
diff changeset
496 from .utils import procutil
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
497
48482
d2fff292c265 pytype: stop excluding statprof.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 48481
diff changeset
498 fp = procutil.stdout
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
499 if len(data.samples) == 0:
40198
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
500 fp.write(b'No samples recorded.\n')
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
501 return
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
502
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
503 if format == DisplayFormats.ByLine:
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
504 display_by_line(data, fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
505 elif format == DisplayFormats.ByMethod:
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
506 display_by_method(data, fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
507 elif format == DisplayFormats.AboutMethod:
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
508 display_about_method(data, fp, **kwargs)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
509 elif format == DisplayFormats.Hotpath:
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
510 display_hotpath(data, fp, **kwargs)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
511 elif format == DisplayFormats.FlameGraph:
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
512 write_to_flame(data, fp, **kwargs)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
513 elif format == DisplayFormats.Json:
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
514 write_to_json(data, fp)
30929
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
515 elif format == DisplayFormats.Chrome:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
516 write_to_chrome(data, fp, **kwargs)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
517 else:
48481
c1fe758c1530 statprof: convert a few exception byte strings to str
Matt Harbison <matt_harbison@yahoo.com>
parents: 46018
diff changeset
518 raise Exception("Invalid display format")
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
519
30929
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
520 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
521 fp.write(b'---\n')
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
522 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
523 fp.write(b'Total time: %f seconds (%f wall)\n' % data.accumulated_time)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
524
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
525
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
526 def display_by_line(data, fp):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
527 """Print the profiler data with each sample line represented
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
528 as one row in a table. Sorted by self-time per line."""
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
529 stats = SiteStats.buildstats(data.samples)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
530 stats.sort(reverse=True, key=lambda x: x.selfseconds())
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
531
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
532 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
533 b'%5.5s %10.10s %7.7s %-8.8s\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
534 % (b'% ', b'cumulative', b'self', b'')
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
535 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
536 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
537 b'%5.5s %9.9s %8.8s %-8.8s\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
538 % (b"time", b"seconds", b"seconds", b"name")
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
539 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
540
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
541 for stat in stats:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
542 site = stat.site
50305
972f3e5c94b8 statprof: with Python 3.12, lineno is (more) often None
Mads Kiilerich <mads@kiilerich.com>
parents: 49806
diff changeset
543 sitelabel = b'%s:%d:%s' % (
972f3e5c94b8 statprof: with Python 3.12, lineno is (more) often None
Mads Kiilerich <mads@kiilerich.com>
parents: 49806
diff changeset
544 site.filename(),
972f3e5c94b8 statprof: with Python 3.12, lineno is (more) often None
Mads Kiilerich <mads@kiilerich.com>
parents: 49806
diff changeset
545 site.lineno or -1,
972f3e5c94b8 statprof: with Python 3.12, lineno is (more) often None
Mads Kiilerich <mads@kiilerich.com>
parents: 49806
diff changeset
546 site.function,
972f3e5c94b8 statprof: with Python 3.12, lineno is (more) often None
Mads Kiilerich <mads@kiilerich.com>
parents: 49806
diff changeset
547 )
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
548 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
549 b'%6.2f %9.2f %9.2f %s\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
550 % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
551 stat.selfpercent(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
552 stat.totalseconds(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
553 stat.selfseconds(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
554 sitelabel,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
555 )
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
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
558
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
559 def display_by_method(data, fp):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
560 """Print the profiler data with each sample function represented
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
561 as one row in a table. Important lines within that function are
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
562 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
563 fp.write(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
564 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
565 % (b'% ', b'cumulative', b'self', b'')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
566 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
567 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
568 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
569 % (b"time", b"seconds", b"seconds", b"name")
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
570 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
571
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
572 stats = SiteStats.buildstats(data.samples)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
573
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
574 grouped = defaultdict(list)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
575 for stat in stats:
40485
8664fdc1cfb3 statprof: clean up unicode/bytes a little
Augie Fackler <augie@google.com>
parents: 40484
diff changeset
576 grouped[stat.site.filename() + b":" + stat.site.function].append(stat)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
577
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
578 # compute sums for each function
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
579 functiondata = []
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
580 for fname, sitestats in grouped.items():
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
581 total_cum_sec = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
582 total_self_sec = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
583 total_percent = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
584 for stat in sitestats:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
585 total_cum_sec += stat.totalseconds()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
586 total_self_sec += stat.selfseconds()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
587 total_percent += stat.selfpercent()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
588
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
589 functiondata.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
590 (fname, total_cum_sec, total_self_sec, total_percent, sitestats)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
591 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
592
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
593 # sort by total self sec
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
594 functiondata.sort(reverse=True, key=lambda x: x[2])
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
595
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
596 for function in functiondata:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
597 if function[3] < 0.05:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
598 continue
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
599 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
600 b'%6.2f %9.2f %9.2f %s\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
601 % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
602 function[3], # total percent
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
603 function[1], # total cum sec
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
604 function[2], # total self sec
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
605 function[0],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
606 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
607 ) # file:function
40198
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
608
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
609 function[4].sort(reverse=True, key=lambda i: i.selfseconds())
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
610 for stat in function[4]:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
611 # only show line numbers for significant locations (>1% time spent)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
612 if stat.selfpercent() > 1:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
613 source = stat.site.getsource(25)
48939
37537a4d2695 statprof: remove superfluous sys.version_info check
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48935
diff changeset
614 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
615 source = pycompat.bytestr(source)
7df42042636d py3: sprinkle statprof.py with utf-8 encoding
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40199
diff changeset
616
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
617 stattuple = (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
618 stat.selfpercent(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
619 stat.selfseconds(),
50305
972f3e5c94b8 statprof: with Python 3.12, lineno is (more) often None
Mads Kiilerich <mads@kiilerich.com>
parents: 49806
diff changeset
620 stat.site.lineno or -1,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
621 source,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
622 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
623
40198
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
624 fp.write(b'%33.0f%% %6.2f line %d: %s\n' % stattuple)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
625
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
626
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
627 def display_about_method(data, fp, function=None, **kwargs):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
628 if function is None:
48481
c1fe758c1530 statprof: convert a few exception byte strings to str
Matt Harbison <matt_harbison@yahoo.com>
parents: 46018
diff changeset
629 raise Exception("Invalid function")
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
630
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
631 filename = None
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
632 if b':' in function:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
633 filename, function = function.split(b':')
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
634
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
635 relevant_samples = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
636 parents = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
637 children = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
638
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
639 for sample in data.samples:
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
640 for i, site in enumerate(sample.stack):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
641 if site.function == function and (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
642 not filename or site.filename() == filename
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
643 ):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
644 relevant_samples += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
645 if i != len(sample.stack) - 1:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
646 parent = sample.stack[i + 1]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
647 if parent in parents:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
648 parents[parent] = parents[parent] + 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
649 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
650 parents[parent] = 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
651
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
652 if site in children:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
653 children[site] = children[site] + 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
654 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
655 children[site] = 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
656
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
657 parents = [(parent, count) for parent, count in parents.items()]
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
658 parents.sort(reverse=True, key=lambda x: x[1])
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
659 for parent, count in parents:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
660 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
661 b'%6.2f%% %s:%s line %s: %s\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
662 % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
663 count / relevant_samples * 100,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
664 pycompat.fsencode(parent.filename()),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
665 pycompat.sysbytes(parent.function),
51173
933551630b0d statprof: handle `lineno == None` in more cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 50929
diff changeset
666 parent.lineno or -1,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
667 pycompat.sysbytes(parent.getsource(50)),
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 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
670
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
671 stats = SiteStats.buildstats(data.samples)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
672 stats = [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
673 s
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
674 for s in stats
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
675 if s.site.function == function
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
676 and (not filename or s.site.filename() == filename)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
677 ]
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
678
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
679 total_cum_sec = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
680 total_self_sec = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
681 total_self_percent = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
682 total_cum_percent = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
683 for stat in stats:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
684 total_cum_sec += stat.totalseconds()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
685 total_self_sec += stat.selfseconds()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
686 total_self_percent += stat.selfpercent()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
687 total_cum_percent += stat.totalpercent()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
688
40198
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
689 fp.write(
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
690 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
691 % (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
692 pycompat.sysbytes(filename or b'___'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
693 pycompat.sysbytes(function),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
694 total_cum_sec,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
695 total_cum_percent,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
696 total_self_sec,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
697 total_self_percent,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
698 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
699 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
700
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
701 children = [(child, count) for child, count in children.items()]
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
702 children.sort(reverse=True, key=lambda x: x[1])
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
703 for child, count in children:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
704 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
705 b' %6.2f%% line %s: %s\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
706 % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
707 count / relevant_samples * 100,
51173
933551630b0d statprof: handle `lineno == None` in more cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 50929
diff changeset
708 child.lineno or -1,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
709 pycompat.sysbytes(child.getsource(50)),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
710 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
711 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
712
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
713
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
714 def display_hotpath(data, fp, limit=0.05, **kwargs):
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48939
diff changeset
715 class HotNode:
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
716 def __init__(self, site):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
717 self.site = site
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
718 self.count = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
719 self.children = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
720
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
721 def add(self, stack, time):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
722 self.count += time
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
723 site = stack[0]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
724 child = self.children.get(site)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
725 if not child:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
726 child = HotNode(site)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
727 self.children[site] = child
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
728
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
729 if len(stack) > 1:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
730 i = 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
731 # 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
732 while i < len(stack) and stack[i].skipname() in skips:
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
733 i += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
734 if i < len(stack):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
735 child.add(stack[i:], time)
46017
068307b638f4 statprof: fix off-by-one-line error in output
Kyle Lippincott <spectral@google.com>
parents: 45942
diff changeset
736 else:
068307b638f4 statprof: fix off-by-one-line error in output
Kyle Lippincott <spectral@google.com>
parents: 45942
diff changeset
737 # Normally this is done by the .add() calls
068307b638f4 statprof: fix off-by-one-line error in output
Kyle Lippincott <spectral@google.com>
parents: 45942
diff changeset
738 child.count += time
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
739
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
740 root = HotNode(None)
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
741 lasttime = data.samples[0].time
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
742 for sample in data.samples:
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
743 root.add(sample.stack[::-1], sample.time - lasttime)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
744 lasttime = sample.time
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
745 showtime = kwargs.get('showtime', True)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
746
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
747 def _write(node, depth, multiple_siblings):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
748 site = node.site
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
749 visiblechildren = [
48935
2cce2fa5bcf7 py3: replace pycompat.itervalues(x) with x.values()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
750 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
751 ]
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
752 if site:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
753 indent = depth * 2 - 1
46017
068307b638f4 statprof: fix off-by-one-line error in output
Kyle Lippincott <spectral@google.com>
parents: 45942
diff changeset
754 filename = (site.filename() + b':').ljust(15)
068307b638f4 statprof: fix off-by-one-line error in output
Kyle Lippincott <spectral@google.com>
parents: 45942
diff changeset
755 function = site.function
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
756
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
757 # lots of string formatting
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
758 listpattern = (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
759 b''.ljust(indent)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
760 + (b'\\' if multiple_siblings else b'|')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
761 + b' %4.1f%%'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
762 + (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
763 + b' %s %s'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
764 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
765 liststring = listpattern % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
766 node.count / root.count * 100,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
767 filename,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
768 function,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
769 )
46018
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46017
diff changeset
770 # 4 to account for the word 'line'
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46017
diff changeset
771 spacing_len = max(4, 55 - len(liststring))
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46017
diff changeset
772 prefix = b''
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46017
diff changeset
773 if spacing_len == 4:
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46017
diff changeset
774 prefix = b', '
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46017
diff changeset
775
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46017
diff changeset
776 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
777 codestring = codepattern % (
46018
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46017
diff changeset
778 prefix,
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46017
diff changeset
779 b'line'.rjust(spacing_len),
49578
aab3d4c05720 profile: prevent a crash when line number is unknown
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
780 site.lineno if site.lineno is not None else -1,
46018
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46017
diff changeset
781 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
782 site.getsource(30),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
783 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
784
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
785 finalstring = liststring + codestring
48935
2cce2fa5bcf7 py3: replace pycompat.itervalues(x) with x.values()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
786 childrensamples = sum([c.count for c in node.children.values()])
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
787 # 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
788 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
789 finalstring = b'\033[91m' + finalstring + b'\033[0m'
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
790 # Make frames that didn't actually perform work dark grey
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
791 elif node.count - childrensamples == 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
792 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
793 fp.write(finalstring + b'\n')
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
794
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
795 newdepth = depth
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
796 if len(visiblechildren) > 1 or multiple_siblings:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
797 newdepth += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
798
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
799 visiblechildren.sort(reverse=True, key=lambda x: x.count)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
800 for child in visiblechildren:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
801 _write(child, newdepth, len(visiblechildren) > 1)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
802
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
803 if root.count > 0:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
804 _write(root, 0, False)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
805
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
806
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
807 def write_to_flame(data, fp, scriptpath=None, outputfile=None, **kwargs):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
808 if scriptpath is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
809 scriptpath = encoding.environ[b'HOME'] + b'/flamegraph.pl'
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
810 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
811 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
812 fp.write(b'get it here: https://github.com/brendangregg/FlameGraph\n')
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
813 return
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
814
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
815 lines = {}
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
816 for sample in data.samples:
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
817 sites = [s.function for s in sample.stack]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
818 sites.reverse()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
819 line = b';'.join(sites)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
820 if line in lines:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
821 lines[line] = lines[line] + 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
822 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
823 lines[line] = 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
824
42835
db6d7cbda80b statprof: use context manager for file when writing flame graph
Martin von Zweigbergk <martinvonz@google.com>
parents: 42834
diff changeset
825 fd, path = pycompat.mkstemp()
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
826
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
827 with open(path, b"w+") as file:
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
828 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
829 file.write(b"%s %d\n" % (line, count))
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
830
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
831 if outputfile is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
832 outputfile = b'~/flamegraph.svg'
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
833
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
834 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
835 fp.write(b'Written to %s\n' % outputfile)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
836
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
837
30928
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
838 _pathcache = {}
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
839
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
840
30928
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
841 def simplifypath(path):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
842 """Attempt to make the path to a Python module easier to read by
30928
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
843 removing whatever part of the Python search path it was found
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
844 on."""
30928
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
845
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
846 if path in _pathcache:
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
847 return _pathcache[path]
42837
cde1c101ab8a py3: make statprof's chrome output work
Martin von Zweigbergk <martinvonz@google.com>
parents: 42836
diff changeset
848 hgpath = encoding.__file__.rsplit(os.sep, 2)[0]
30928
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
849 for p in [hgpath] + sys.path:
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
850 prefix = p + os.sep
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
851 if path.startswith(prefix):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
852 path = path[len(prefix) :]
30928
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
853 break
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
854 _pathcache[path] = path
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
855 return path
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
856
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
857
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
858 def write_to_json(data, fp):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
859 samples = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
860
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
861 for sample in data.samples:
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
862 stack = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
863
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
864 for frame in sample.stack:
40485
8664fdc1cfb3 statprof: clean up unicode/bytes a little
Augie Fackler <augie@google.com>
parents: 40484
diff changeset
865 stack.append(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
866 (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
867 pycompat.sysstr(frame.path),
51173
933551630b0d statprof: handle `lineno == None` in more cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 50929
diff changeset
868 frame.lineno or -1,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
869 pycompat.sysstr(frame.function),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
870 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
871 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
872
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
873 samples.append((sample.time, stack))
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
874
40191
4b7eb862692e py3: encode json output to bytes and use write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39092
diff changeset
875 data = json.dumps(samples)
4b7eb862692e py3: encode json output to bytes and use write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39092
diff changeset
876 if not isinstance(data, bytes):
4b7eb862692e py3: encode json output to bytes and use write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39092
diff changeset
877 data = data.encode('utf-8')
4b7eb862692e py3: encode json output to bytes and use write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39092
diff changeset
878
4b7eb862692e py3: encode json output to bytes and use write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39092
diff changeset
879 fp.write(data)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
880
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
881
30929
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
882 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: 30928
diff changeset
883 samples = []
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
884 laststack = collections.deque()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
885 lastseen = collections.deque()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
886
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
887 # 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: 30928
diff changeset
888 # 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: 30928
diff changeset
889 # 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: 30928
diff changeset
890 stack2id = {}
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
891 id2stack = [] # will eventually be rendered
30929
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
892
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
893 def stackid(stack):
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
894 if not stack:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
895 return
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
896 if stack in stack2id:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
897 return stack2id[stack]
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
898 parent = stackid(stack[1:])
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
899 myid = len(stack2id)
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
900 stack2id[stack] = myid
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
901 id2stack.append(dict(category=stack[0][0], name='%s %s' % stack[0]))
30929
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
902 if parent is not None:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
903 id2stack[-1].update(parent=parent)
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
904 return myid
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
905
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
906 # 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: 30928
diff changeset
907 # 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: 30928
diff changeset
908 # 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: 30928
diff changeset
909 # 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: 30928
diff changeset
910 # millisecond in length.
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
911
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
912 clamp = 0.001
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
913
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
914 # 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: 30928
diff changeset
915 # frames that are too noisy:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
916 #
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
917 # * 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: 30928
diff changeset
918 # 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: 30928
diff changeset
919 #
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
920 # * 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: 30928
diff changeset
921 # 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: 30928
diff changeset
922
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
923 blacklist = set()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
924 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: 30928
diff changeset
925 minthreshold = totaltime * minthreshold
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
926 maxthreshold = max(totaltime * maxthreshold, clamp)
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
927
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
928 def poplast():
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
929 oldsid = stackid(tuple(laststack))
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
930 oldcat, oldfunc = laststack.popleft()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
931 oldtime, oldidx = lastseen.popleft()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
932 duration = sample.time - oldtime
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
933 if minthreshold <= duration <= maxthreshold:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
934 # ensure no zero-duration events
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
935 sampletime = max(oldtime + clamp, sample.time)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
936 samples.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
937 dict(
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
938 ph='E',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
939 name=oldfunc,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
940 cat=oldcat,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
941 sf=oldsid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
942 ts=sampletime * 1e6,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
943 pid=0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
944 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
945 )
30929
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
946 else:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
947 blacklist.add(oldidx)
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
948
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
949 # 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: 30928
diff changeset
950 # events given only stack snapshots.
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
951
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
952 for sample in data.samples:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
953 stack = tuple(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
954 (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
955 (
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
956 '%s:%d'
51173
933551630b0d statprof: handle `lineno == None` in more cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 50929
diff changeset
957 % (
933551630b0d statprof: handle `lineno == None` in more cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 50929
diff changeset
958 simplifypath(pycompat.sysstr(frame.path)),
933551630b0d statprof: handle `lineno == None` in more cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 50929
diff changeset
959 frame.lineno or -1,
933551630b0d statprof: handle `lineno == None` in more cases
Martin von Zweigbergk <martinvonz@google.com>
parents: 50929
diff changeset
960 ),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
961 pycompat.sysstr(frame.function),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
962 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
963 for frame in sample.stack
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
964 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
965 )
30929
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
966 qstack = collections.deque(stack)
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
967 if laststack == qstack:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
968 continue
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
969 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: 30928
diff changeset
970 laststack.pop()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
971 qstack.pop()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
972 while laststack:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
973 poplast()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
974 for f in reversed(qstack):
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
975 lastseen.appendleft((sample.time, len(samples)))
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
976 laststack.appendleft(f)
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
977 path, name = f
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
978 sid = stackid(tuple(laststack))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
979 samples.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
980 dict(
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
981 ph='B',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
982 name=name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
983 cat=path,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
984 ts=sample.time * 1e6,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
985 sf=sid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
986 pid=0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
987 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
988 )
30929
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
989 laststack = collections.deque(stack)
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
990 while laststack:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
991 poplast()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
992 events = [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
993 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
994 ]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
995 frames = collections.OrderedDict(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
996 (str(k), v) for (k, v) in enumerate(id2stack)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
997 )
42836
cd3b5be5515d py3: for statprof's Chrome output, write json to string, then encode to bytes
Martin von Zweigbergk <martinvonz@google.com>
parents: 42835
diff changeset
998 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: 42835
diff changeset
999 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: 42835
diff changeset
1000 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: 42835
diff changeset
1001 fp.write(data)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1002 fp.write(b'\n')
30929
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
1003
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1004
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1005 def printusage():
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1006 print(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1007 r"""
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1008 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
1009 the following forms:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1010
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1011 usage:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1012 hotpath [-l --limit percent]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1013 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
1014 Red calls take over 10%% of the total time themselves.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1015 lines
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1016 Shows the actual sampled lines.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1017 functions
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1018 Shows the samples grouped by function.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1019 function [filename:]functionname
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1020 Shows the callers and callees of a particular function.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1021 flame [-s --script-path] [-o --output-file path]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1022 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
1023 Requires that ~/flamegraph.pl exist.
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1024 (Specify alternate script path with --script-path.)"""
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1025 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1026
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1027
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1028 def main(argv=None):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1029 if argv is None:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1030 argv = sys.argv
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1031
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1032 if len(argv) == 1:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1033 printusage()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1034 return 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1035
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1036 displayargs = {}
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 optstart = 2
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1039 displayargs[b'function'] = None
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
1040 if argv[1] == 'hotpath':
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1041 displayargs[b'format'] = DisplayFormats.Hotpath
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
1042 elif argv[1] == 'lines':
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1043 displayargs[b'format'] = DisplayFormats.ByLine
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
1044 elif argv[1] == 'functions':
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1045 displayargs[b'format'] = DisplayFormats.ByMethod
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
1046 elif argv[1] == 'function':
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1047 displayargs[b'format'] = DisplayFormats.AboutMethod
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1048 displayargs[b'function'] = argv[2]
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1049 optstart = 3
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
1050 elif argv[1] == 'flame':
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1051 displayargs[b'format'] = DisplayFormats.FlameGraph
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1052 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1053 printusage()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1054 return 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1055
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1056 # process options
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1057 try:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1058 opts, args = pycompat.getoptb(
49806
9eb69fa5a783 statprof: don't pass str `sys.argv` to a function expecting bytes
Matt Harbison <matt_harbison@yahoo.com>
parents: 49578
diff changeset
1059 pycompat.sysargv[optstart:],
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1060 b"hl:f:o:p:",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1061 [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
1062 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1063 except getopt.error as msg:
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
1064 print(msg)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1065 printusage()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1066 return 2
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1067
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1068 displayargs[b'limit'] = 0.05
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1069 path = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1070 for o, value in opts:
43503
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
1071 if o in ("-l", "--limit"):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1072 displayargs[b'limit'] = float(value)
43503
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
1073 elif o in ("-f", "--file"):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1074 path = value
43503
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
1075 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
1076 displayargs[b'outputfile'] = value
43503
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
1077 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
1078 displayargs[b'scriptpath'] = value
43503
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
1079 elif o in ("-h", "help"):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1080 printusage()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1081 return 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1082 else:
48481
c1fe758c1530 statprof: convert a few exception byte strings to str
Matt Harbison <matt_harbison@yahoo.com>
parents: 46018
diff changeset
1083 assert False, "unhandled option %s" % o
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1084
30845
262c2be8ea5a statprof: require input file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30637
diff changeset
1085 if not path:
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
1086 print('must specify --file to load')
30845
262c2be8ea5a statprof: require input file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30637
diff changeset
1087 return 1
262c2be8ea5a statprof: require input file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30637
diff changeset
1088
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1089 load_data(path=path)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1090
35370
c5853c9a6545 py3: handle keyword arguments correctly in statprof.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32291
diff changeset
1091 display(**pycompat.strkwargs(displayargs))
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1092
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1093 return 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1094
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1095
43503
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
1096 if __name__ == "__main__":
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1097 sys.exit(main())