annotate mercurial/statprof.py @ 47338:f27f2afb15da

dirstate-tree: Skip readdir() in `hg status -mard` When running the status algorithm in a mode where we don’t list unknown or ignored files, all we care about are files that are listed in the dirstate. We can there for skip making expensive calls to readdir() to list the contents of filesystem directories, and instead only run stat() to get the filesystem state of files listed in the dirstate. (This state may be an error for files that don’t exist anymore on the filesystem.) On 16 CPU threads, this reduces the time spent in the `status()` function for `hg status -mard` on an old snapshot of mozilla-central from ~70ms to ~50ms. Differential Revision: https://phab.mercurial-scm.org/D10752
author Simon Sapin <simon.sapin@octobus.net>
date Wed, 19 May 2021 16:18:16 +0200
parents 8b0a3ff5ed12
children c1fe758c1530
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
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
104 from __future__ import absolute_import, division, print_function
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
105
30256
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
106 import collections
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
107 import contextlib
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
108 import getopt
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
109 import inspect
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
110 import json
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
111 import os
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
112 import signal
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
113 import sys
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
114 import threading
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
115 import time
30256
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
116
43085
eef9a2d67051 py3: manually import pycompat.open into files that need it
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
117 from .pycompat import open
30578
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30568
diff changeset
118 from . import (
30637
344e68882cd3 py3: replace os.environ with encoding.environ (part 4 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30578
diff changeset
119 encoding,
30578
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30568
diff changeset
120 pycompat,
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30568
diff changeset
121 )
c6ce11f2ee50 py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30568
diff changeset
122
30256
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
123 defaultdict = collections.defaultdict
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
124 contextmanager = contextlib.contextmanager
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
125
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
126 __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
127
40196
2864f8d3fcd6 py3: use raw strings for stack names
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40191
diff changeset
128 skips = {
43503
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
129 "util.py:check",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
130 "extensions.py:closure",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
131 "color.py:colorcmd",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
132 "dispatch.py:checkargs",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
133 "dispatch.py:<lambda>",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
134 "dispatch.py:_runcatch",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
135 "dispatch.py:_dispatch",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
136 "dispatch.py:_runcommand",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
137 "pager.py:pagecmd",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
138 "dispatch.py:run",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
139 "dispatch.py:dispatch",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
140 "dispatch.py:runcommand",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
141 "hg.py:<module>",
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43461
diff changeset
142 "evolve.py:warnobserrors",
32291
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 31074
diff changeset
143 }
30253
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 ###########################################################################
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
146 ## Utils
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
147
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
148
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
149 def clock():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
150 times = os.times()
38259
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38164
diff changeset
151 return (times[0] + times[1], times[4])
30253
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 ###########################################################################
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
155 ## Collection data structures
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
156
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
157
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
158 class ProfileState(object):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
159 def __init__(self, frequency=None):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
160 self.reset(frequency)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
161 self.track = b'cpu'
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
162
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
163 def reset(self, frequency=None):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
164 # total so far
38259
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38164
diff changeset
165 self.accumulated_time = (0.0, 0.0)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
166 # start_time when timer is active
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
167 self.last_start_time = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
168 # a float
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
169 if frequency:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
170 self.sample_interval = 1.0 / frequency
43088
0d612db7047c py3: stop injecting pycompat.hasattr into modules
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
171 elif not pycompat.hasattr(self, 'sample_interval'):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
172 # default to 1000 Hz
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
173 self.sample_interval = 1.0 / 1000.0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
174 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
175 # leave the frequency as it was
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
176 pass
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
177 self.remaining_prof_time = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
178 # for user start/stop nesting
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
179 self.profile_level = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
180
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
181 self.samples = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
182
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
183 def accumulate_time(self, stop_time):
38259
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38164
diff changeset
184 increment = (
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38164
diff changeset
185 stop_time[0] - self.last_start_time[0],
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38164
diff changeset
186 stop_time[1] - self.last_start_time[1],
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38164
diff changeset
187 )
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38164
diff changeset
188 self.accumulated_time = (
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38164
diff changeset
189 self.accumulated_time[0] + increment[0],
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38164
diff changeset
190 self.accumulated_time[1] + increment[1],
af402c6b90db statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents: 38164
diff changeset
191 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
192
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
193 def seconds_per_sample(self):
38260
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
194 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
195
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
196 @property
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
197 def timeidx(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
198 if self.track == b'real':
38260
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
199 return 1
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
200 return 0
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
201
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
202
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
203 state = ProfileState()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
204
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
205
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
206 class CodeSite(object):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
207 cache = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
208
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
209 __slots__ = ('path', 'lineno', 'function', 'source')
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
210
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
211 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
212 assert isinstance(path, bytes)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
213 self.path = path
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
214 self.lineno = lineno
40484
93501a5fd62b statprof: add a couple of asserts to avoid storing unicodes
Augie Fackler <augie@google.com>
parents: 40385
diff changeset
215 assert isinstance(function, bytes)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
216 self.function = function
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
217 self.source = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
218
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
219 def __eq__(self, other):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
220 try:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
221 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
222 except:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
223 return False
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
224
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
225 def __hash__(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
226 return hash((self.lineno, self.path))
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
227
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
228 @classmethod
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
229 def get(cls, path, lineno, function):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
230 k = (path, lineno)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
231 try:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
232 return cls.cache[k]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
233 except KeyError:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
234 v = cls(path, lineno, function)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
235 cls.cache[k] = v
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
236 return v
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
237
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
238 def getsource(self, length):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
239 if self.source is None:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
240 lineno = self.lineno - 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
241 try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
242 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
243 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
244 if i == lineno:
c085cb134b9e statprof: use context manager when reading source from file
Martin von Zweigbergk <martinvonz@google.com>
parents: 42833
diff changeset
245 self.source = line.strip()
c085cb134b9e statprof: use context manager when reading source from file
Martin von Zweigbergk <martinvonz@google.com>
parents: 42833
diff changeset
246 break
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
247 except:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
248 pass
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
249 if self.source is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
250 self.source = b''
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
251
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
252 source = self.source
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
253 if len(source) > length:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
254 source = source[: (length - 3)] + b"..."
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
255 return source
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
256
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
257 def filename(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
258 return os.path.basename(self.path)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
259
40385
cc4586749c8c statprof: fix overflow while skipping boilerplate parts
Yuya Nishihara <yuya@tcha.org>
parents: 40384
diff changeset
260 def skipname(self):
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
261 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
262
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
263
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
264 class Sample(object):
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
265 __slots__ = ('stack', 'time')
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
266
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
267 def __init__(self, stack, time):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
268 self.stack = stack
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
269 self.time = time
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
270
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
271 @classmethod
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
272 def from_frame(cls, frame, time):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
273 stack = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
274
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
275 while frame:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
276 stack.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
277 CodeSite.get(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
278 pycompat.sysbytes(frame.f_code.co_filename),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
279 frame.f_lineno,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
280 pycompat.sysbytes(frame.f_code.co_name),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
281 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
282 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
283 frame = frame.f_back
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
284
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
285 return Sample(stack, time)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
286
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
287
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
288 ###########################################################################
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
289 ## SIGPROF handler
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
290
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
291
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
292 def profile_signal_handler(signum, frame):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
293 if state.profile_level > 0:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
294 now = clock()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
295 state.accumulate_time(now)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
296
38260
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
297 timestamp = state.accumulated_time[state.timeidx]
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
298 state.samples.append(Sample.from_frame(frame, timestamp))
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
299
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
300 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
301 state.last_start_time = now
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
302
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
303
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
304 stopthread = threading.Event()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
305
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
306
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
307 def samplerthread(tid):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
308 while not stopthread.is_set():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
309 now = clock()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
310 state.accumulate_time(now)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
311
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
312 frame = sys._current_frames()[tid]
38260
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
313
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
314 timestamp = state.accumulated_time[state.timeidx]
15a1e37f80bd profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents: 38259
diff changeset
315 state.samples.append(Sample.from_frame(frame, timestamp))
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
316
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
317 state.last_start_time = now
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
318 time.sleep(state.sample_interval)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
319
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
320 stopthread.clear()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
321
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
322
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
323 ###########################################################################
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
324 ## Profiling API
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
325
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
326
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
327 def is_active():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
328 return state.profile_level > 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
329
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
330
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
331 lastmechanism = None
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
332
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
333
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
334 def start(mechanism=b'thread', track=b'cpu'):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
335 '''Install the profiling signal handler, and start profiling.'''
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
336 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
337 state.profile_level += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
338 if state.profile_level == 1:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
339 state.last_start_time = clock()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
340 rpt = state.remaining_prof_time
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
341 state.remaining_prof_time = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
342
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
343 global lastmechanism
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
344 lastmechanism = mechanism
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
345
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
346 if mechanism == b'signal':
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
347 signal.signal(signal.SIGPROF, profile_signal_handler)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
348 signal.setitimer(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
349 signal.ITIMER_PROF, rpt or state.sample_interval, 0.0
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
350 )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
351 elif mechanism == b'thread':
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
352 frame = inspect.currentframe()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
353 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
354 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
355 target=samplerthread, args=(tid,), name="samplerthread"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
356 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
357 state.thread.start()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
358
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
359
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
360 def stop():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
361 '''Stop profiling, and uninstall the profiling signal handler.'''
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
362 state.profile_level -= 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
363 if state.profile_level == 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
364 if lastmechanism == b'signal':
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
365 rpt = signal.setitimer(signal.ITIMER_PROF, 0.0, 0.0)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
366 signal.signal(signal.SIGPROF, signal.SIG_IGN)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
367 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
368 elif lastmechanism == b'thread':
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
369 stopthread.set()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
370 state.thread.join()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
371
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
372 state.accumulate_time(clock())
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
373 state.last_start_time = None
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
374 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
375 if statprofpath:
f42cd5434cc2 statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30254
diff changeset
376 save_data(statprofpath)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
377
30299
1e5346313963 statprof: return state from stop()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30258
diff changeset
378 return state
1e5346313963 statprof: return state from stop()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30258
diff changeset
379
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
380
30255
f42cd5434cc2 statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30254
diff changeset
381 def save_data(path):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
382 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
383 file.write(b"%f %f\n" % state.accumulated_time)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
384 for sample in state.samples:
40197
113adb1b3f24 py3: use %d in a few places
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40196
diff changeset
385 time = sample.time
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
386 stack = sample.stack
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
387 sites = [
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
388 b'\1'.join([s.path, b'%d' % s.lineno, s.function])
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
389 for s in stack
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
390 ]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
391 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
392
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
393
30255
f42cd5434cc2 statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30254
diff changeset
394 def load_data(path):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
395 lines = open(path, b'rb').read().splitlines()
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
396
38274
99188a7c8717 statprof: fix save and load
Boris Feld <boris.feld@octobus.net>
parents: 38260
diff changeset
397 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
398 state.samples = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
399 for line in lines[1:]:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
400 parts = line.split(b'\0')
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
401 time = float(parts[0])
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
402 rawsites = parts[1:]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
403 sites = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
404 for rawsite in rawsites:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
405 siteparts = rawsite.split(b'\1')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
406 sites.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
407 CodeSite.get(siteparts[0], int(siteparts[1]), siteparts[2])
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
408 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
409
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
410 state.samples.append(Sample(sites, time))
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
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
413 def reset(frequency=None):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
414 """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
415 profiler is running.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
416
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
417 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
418 collect per second."""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
419 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
420 CodeSite.cache.clear()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
421 state.reset(frequency)
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
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
424 @contextmanager
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
425 def profile():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
426 start()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
427 try:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
428 yield
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
429 finally:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
430 stop()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
431 display()
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 ###########################################################################
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
435 ## Reporting API
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
436
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
437
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
438 class SiteStats(object):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
439 def __init__(self, site):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
440 self.site = site
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
441 self.selfcount = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
442 self.totalcount = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
443
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
444 def addself(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
445 self.selfcount += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
446
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
447 def addtotal(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
448 self.totalcount += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
449
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
450 def selfpercent(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
451 return self.selfcount / len(state.samples) * 100
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
452
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
453 def totalpercent(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
454 return self.totalcount / len(state.samples) * 100
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
455
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
456 def selfseconds(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
457 return self.selfcount * state.seconds_per_sample()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
458
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
459 def totalseconds(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
460 return self.totalcount * state.seconds_per_sample()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
461
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
462 @classmethod
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
463 def buildstats(cls, samples):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
464 stats = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
465
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
466 for sample in samples:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
467 for i, site in enumerate(sample.stack):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
468 sitestat = stats.get(site)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
469 if not sitestat:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
470 sitestat = SiteStats(site)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
471 stats[site] = sitestat
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
472
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
473 sitestat.addtotal()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
474
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
475 if i == 0:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
476 sitestat.addself()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
477
43104
74802979dd9d py3: define and use pycompat.itervalues()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43088
diff changeset
478 return [s for s in pycompat.itervalues(stats)]
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
479
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
480
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
481 class DisplayFormats:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
482 ByLine = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
483 ByMethod = 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
484 AboutMethod = 2
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
485 Hotpath = 3
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
486 FlameGraph = 4
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
487 Json = 5
30929
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
488 Chrome = 6
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
489
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
490
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
491 def display(fp=None, format=3, data=None, **kwargs):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
492 '''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
493 if data is None:
3c569172848d statprof: small if cleanup
Boris Feld <boris.feld@octobus.net>
parents: 38274
diff changeset
494 data = state
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
495
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
496 if fp is None:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
497 import sys
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
498
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
499 fp = sys.stdout
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
500 if len(data.samples) == 0:
40198
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
501 fp.write(b'No samples recorded.\n')
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
502 return
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
503
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
504 if format == DisplayFormats.ByLine:
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
505 display_by_line(data, fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
506 elif format == DisplayFormats.ByMethod:
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
507 display_by_method(data, fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
508 elif format == DisplayFormats.AboutMethod:
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
509 display_about_method(data, fp, **kwargs)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
510 elif format == DisplayFormats.Hotpath:
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
511 display_hotpath(data, fp, **kwargs)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
512 elif format == DisplayFormats.FlameGraph:
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
513 write_to_flame(data, fp, **kwargs)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
514 elif format == DisplayFormats.Json:
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
515 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
516 elif format == DisplayFormats.Chrome:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
517 write_to_chrome(data, fp, **kwargs)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
518 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
519 raise Exception(b"Invalid display format")
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
520
30929
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
521 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
522 fp.write(b'---\n')
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
523 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
524 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
525
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
526
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
527 def display_by_line(data, fp):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
528 """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
529 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
530 stats = SiteStats.buildstats(data.samples)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
531 stats.sort(reverse=True, key=lambda x: x.selfseconds())
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
532
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
533 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
534 b'%5.5s %10.10s %7.7s %-8.8s\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
535 % (b'% ', b'cumulative', b'self', b'')
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
536 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
537 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
538 b'%5.5s %9.9s %8.8s %-8.8s\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
539 % (b"time", b"seconds", b"seconds", b"name")
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
540 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
541
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
542 for stat in stats:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
543 site = stat.site
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
544 sitelabel = b'%s:%d:%s' % (site.filename(), site.lineno, site.function)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
545 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
546 b'%6.2f %9.2f %9.2f %s\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
547 % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
548 stat.selfpercent(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
549 stat.totalseconds(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
550 stat.selfseconds(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
551 sitelabel,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
552 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
553 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
554
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
555
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
556 def display_by_method(data, fp):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
557 """Print the profiler data with each sample function represented
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
558 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
559 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
560 fp.write(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
561 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
562 % (b'% ', b'cumulative', b'self', b'')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
563 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
564 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
565 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
566 % (b"time", b"seconds", b"seconds", b"name")
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
567 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
568
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
569 stats = SiteStats.buildstats(data.samples)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
570
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
571 grouped = defaultdict(list)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
572 for stat in stats:
40485
8664fdc1cfb3 statprof: clean up unicode/bytes a little
Augie Fackler <augie@google.com>
parents: 40484
diff changeset
573 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
574
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
575 # compute sums for each function
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
576 functiondata = []
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43104
diff changeset
577 for fname, sitestats in pycompat.iteritems(grouped):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
578 total_cum_sec = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
579 total_self_sec = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
580 total_percent = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
581 for stat in sitestats:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
582 total_cum_sec += stat.totalseconds()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
583 total_self_sec += stat.selfseconds()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
584 total_percent += stat.selfpercent()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
585
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
586 functiondata.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
587 (fname, total_cum_sec, total_self_sec, total_percent, sitestats)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
588 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
589
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
590 # sort by total self sec
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
591 functiondata.sort(reverse=True, key=lambda x: x[2])
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 for function in functiondata:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
594 if function[3] < 0.05:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
595 continue
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
596 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
597 b'%6.2f %9.2f %9.2f %s\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
598 % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
599 function[3], # total percent
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
600 function[1], # total cum sec
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
601 function[2], # total self sec
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
602 function[0],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
603 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
604 ) # file:function
40198
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
605
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
606 function[4].sort(reverse=True, key=lambda i: i.selfseconds())
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
607 for stat in function[4]:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
608 # only show line numbers for significant locations (>1% time spent)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
609 if stat.selfpercent() > 1:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
610 source = stat.site.getsource(25)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
611 if sys.version_info.major >= 3 and not isinstance(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
612 source, bytes
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
613 ):
40201
7df42042636d py3: sprinkle statprof.py with utf-8 encoding
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40199
diff changeset
614 source = pycompat.bytestr(source)
7df42042636d py3: sprinkle statprof.py with utf-8 encoding
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40199
diff changeset
615
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
616 stattuple = (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
617 stat.selfpercent(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
618 stat.selfseconds(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
619 stat.site.lineno,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
620 source,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
621 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
622
40198
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
623 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
624
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
625
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
626 def display_about_method(data, fp, function=None, **kwargs):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
627 if function is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
628 raise Exception(b"Invalid function")
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
629
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
630 filename = None
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
631 if b':' in function:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
632 filename, function = function.split(b':')
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
633
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
634 relevant_samples = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
635 parents = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
636 children = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
637
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
638 for sample in data.samples:
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
639 for i, site in enumerate(sample.stack):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
640 if site.function == function and (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
641 not filename or site.filename() == filename
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
642 ):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
643 relevant_samples += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
644 if i != len(sample.stack) - 1:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
645 parent = sample.stack[i + 1]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
646 if parent in parents:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
647 parents[parent] = parents[parent] + 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
648 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
649 parents[parent] = 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
650
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
651 if site in children:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
652 children[site] = children[site] + 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
653 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
654 children[site] = 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
655
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43104
diff changeset
656 parents = [(parent, count) for parent, count in pycompat.iteritems(parents)]
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
657 parents.sort(reverse=True, key=lambda x: x[1])
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
658 for parent, count in parents:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
659 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
660 b'%6.2f%% %s:%s line %s: %s\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
661 % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
662 count / relevant_samples * 100,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
663 pycompat.fsencode(parent.filename()),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
664 pycompat.sysbytes(parent.function),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
665 parent.lineno,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
666 pycompat.sysbytes(parent.getsource(50)),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
667 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
668 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
669
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
670 stats = SiteStats.buildstats(data.samples)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
671 stats = [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
672 s
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
673 for s in stats
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
674 if s.site.function == function
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
675 and (not filename or s.site.filename() == filename)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
676 ]
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
677
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
678 total_cum_sec = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
679 total_self_sec = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
680 total_self_percent = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
681 total_cum_percent = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
682 for stat in stats:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
683 total_cum_sec += stat.totalseconds()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
684 total_self_sec += stat.selfseconds()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
685 total_self_percent += stat.selfpercent()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
686 total_cum_percent += stat.totalpercent()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
687
40198
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
688 fp.write(
9d3034348c4f py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40197
diff changeset
689 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
690 % (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
691 pycompat.sysbytes(filename or b'___'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
692 pycompat.sysbytes(function),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
693 total_cum_sec,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
694 total_cum_percent,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
695 total_self_sec,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
696 total_self_percent,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
697 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
698 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
699
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43104
diff changeset
700 children = [(child, count) for child, count in pycompat.iteritems(children)]
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
701 children.sort(reverse=True, key=lambda x: x[1])
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
702 for child, count in children:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
703 fp.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
704 b' %6.2f%% line %s: %s\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
705 % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
706 count / relevant_samples * 100,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
707 child.lineno,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
708 pycompat.sysbytes(child.getsource(50)),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
709 )
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
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
712
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
713 def display_hotpath(data, fp, limit=0.05, **kwargs):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
714 class HotNode(object):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
715 def __init__(self, site):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
716 self.site = site
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
717 self.count = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
718 self.children = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
719
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
720 def add(self, stack, time):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
721 self.count += time
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
722 site = stack[0]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
723 child = self.children.get(site)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
724 if not child:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
725 child = HotNode(site)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
726 self.children[site] = child
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
727
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
728 if len(stack) > 1:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
729 i = 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
730 # 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
731 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
732 i += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
733 if i < len(stack):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
734 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
735 else:
068307b638f4 statprof: fix off-by-one-line error in output
Kyle Lippincott <spectral@google.com>
parents: 45942
diff changeset
736 # 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
737 child.count += time
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
738
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
739 root = HotNode(None)
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
740 lasttime = data.samples[0].time
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
741 for sample in data.samples:
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
742 root.add(sample.stack[::-1], sample.time - lasttime)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
743 lasttime = sample.time
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
744 showtime = kwargs.get('showtime', True)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
745
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
746 def _write(node, depth, multiple_siblings):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
747 site = node.site
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
748 visiblechildren = [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
749 c
43104
74802979dd9d py3: define and use pycompat.itervalues()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43088
diff changeset
750 for c in pycompat.itervalues(node.children)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
751 if c.count >= (limit * root.count)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
752 ]
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
753 if site:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
754 indent = depth * 2 - 1
46017
068307b638f4 statprof: fix off-by-one-line error in output
Kyle Lippincott <spectral@google.com>
parents: 45942
diff changeset
755 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
756 function = site.function
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
757
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
758 # lots of string formatting
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
759 listpattern = (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
760 b''.ljust(indent)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
761 + (b'\\' if multiple_siblings else b'|')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
762 + b' %4.1f%%'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
763 + (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
764 + b' %s %s'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
765 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
766 liststring = listpattern % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
767 node.count / root.count * 100,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
768 filename,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
769 function,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
770 )
46018
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46017
diff changeset
771 # 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
772 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
773 prefix = b''
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46017
diff changeset
774 if spacing_len == 4:
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46017
diff changeset
775 prefix = b', '
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46017
diff changeset
776
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46017
diff changeset
777 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
778 codestring = codepattern % (
46018
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46017
diff changeset
779 prefix,
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46017
diff changeset
780 b'line'.rjust(spacing_len),
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
781 site.lineno,
46018
8b0a3ff5ed12 statprof: separate functions and "line", assume 4 digit line numbers
Kyle Lippincott <spectral@google.com>
parents: 46017
diff changeset
782 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
783 site.getsource(30),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
784 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
785
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
786 finalstring = liststring + codestring
43104
74802979dd9d py3: define and use pycompat.itervalues()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43088
diff changeset
787 childrensamples = sum(
74802979dd9d py3: define and use pycompat.itervalues()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43088
diff changeset
788 [c.count for c in pycompat.itervalues(node.children)]
74802979dd9d py3: define and use pycompat.itervalues()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43088
diff changeset
789 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
790 # 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
791 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
792 finalstring = b'\033[91m' + finalstring + b'\033[0m'
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
793 # Make frames that didn't actually perform work dark grey
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
794 elif node.count - childrensamples == 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
795 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
796 fp.write(finalstring + b'\n')
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
797
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
798 newdepth = depth
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
799 if len(visiblechildren) > 1 or multiple_siblings:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
800 newdepth += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
801
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
802 visiblechildren.sort(reverse=True, key=lambda x: x.count)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
803 for child in visiblechildren:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
804 _write(child, newdepth, len(visiblechildren) > 1)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
805
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
806 if root.count > 0:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
807 _write(root, 0, False)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
808
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
809
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
810 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
811 if scriptpath is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
812 scriptpath = encoding.environ[b'HOME'] + b'/flamegraph.pl'
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
813 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
814 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
815 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
816 return
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
817
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
818 lines = {}
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
819 for sample in data.samples:
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
820 sites = [s.function for s in sample.stack]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
821 sites.reverse()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
822 line = b';'.join(sites)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
823 if line in lines:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
824 lines[line] = lines[line] + 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
825 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
826 lines[line] = 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
827
42835
db6d7cbda80b statprof: use context manager for file when writing flame graph
Martin von Zweigbergk <martinvonz@google.com>
parents: 42834
diff changeset
828 fd, path = pycompat.mkstemp()
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
829
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
830 with open(path, b"w+") as file:
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43104
diff changeset
831 for line, count in pycompat.iteritems(lines):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
832 file.write(b"%s %d\n" % (line, count))
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
833
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
834 if outputfile is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
835 outputfile = b'~/flamegraph.svg'
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
836
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
837 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
838 fp.write(b'Written to %s\n' % outputfile)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
839
43076
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 _pathcache = {}
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
842
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
843
30928
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
844 def simplifypath(path):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
845 """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
846 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
847 on."""
30928
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
848
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
849 if path in _pathcache:
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
850 return _pathcache[path]
42837
cde1c101ab8a py3: make statprof's chrome output work
Martin von Zweigbergk <martinvonz@google.com>
parents: 42836
diff changeset
851 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
852 for p in [hgpath] + sys.path:
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
853 prefix = p + os.sep
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
854 if path.startswith(prefix):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
855 path = path[len(prefix) :]
30928
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
856 break
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
857 _pathcache[path] = path
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
858 return path
be3a4fde38eb statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents: 30845
diff changeset
859
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
860
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
861 def write_to_json(data, fp):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
862 samples = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
863
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
864 for sample in data.samples:
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
865 stack = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
866
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
867 for frame in sample.stack:
40485
8664fdc1cfb3 statprof: clean up unicode/bytes a little
Augie Fackler <augie@google.com>
parents: 40484
diff changeset
868 stack.append(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
869 (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
870 pycompat.sysstr(frame.path),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
871 frame.lineno,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
872 pycompat.sysstr(frame.function),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
873 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
874 )
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
875
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
876 samples.append((sample.time, stack))
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
877
40191
4b7eb862692e py3: encode json output to bytes and use write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39092
diff changeset
878 data = json.dumps(samples)
4b7eb862692e py3: encode json output to bytes and use write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39092
diff changeset
879 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
880 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
881
4b7eb862692e py3: encode json output to bytes and use write()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39092
diff changeset
882 fp.write(data)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
883
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
884
30929
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
885 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
886 samples = []
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
887 laststack = collections.deque()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
888 lastseen = collections.deque()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
889
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
890 # 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
891 # 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
892 # 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
893 stack2id = {}
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
894 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
895
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
896 def stackid(stack):
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
897 if not stack:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
898 return
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
899 if stack in stack2id:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
900 return stack2id[stack]
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
901 parent = stackid(stack[1:])
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
902 myid = len(stack2id)
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
903 stack2id[stack] = myid
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
904 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
905 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
906 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
907 return myid
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
908
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
909 # 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
910 # 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
911 # 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
912 # 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
913 # millisecond in length.
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
914
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
915 clamp = 0.001
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 # 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
918 # 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
919 #
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
920 # * 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
921 # 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
922 #
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
923 # * 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
924 # 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
925
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
926 blacklist = set()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
927 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
928 minthreshold = totaltime * minthreshold
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
929 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
930
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
931 def poplast():
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
932 oldsid = stackid(tuple(laststack))
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
933 oldcat, oldfunc = laststack.popleft()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
934 oldtime, oldidx = lastseen.popleft()
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
935 duration = sample.time - oldtime
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
936 if minthreshold <= duration <= maxthreshold:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
937 # 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
938 sampletime = max(oldtime + clamp, sample.time)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
939 samples.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
940 dict(
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
941 ph='E',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
942 name=oldfunc,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
943 cat=oldcat,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
944 sf=oldsid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
945 ts=sampletime * 1e6,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
946 pid=0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
947 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
948 )
30929
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
949 else:
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
950 blacklist.add(oldidx)
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 # 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
953 # 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
954
cb440e7af05d statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents: 30928
diff changeset
955 for sample in data.samples:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
956 stack = tuple(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
957 (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
958 (
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
959 '%s:%d'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
960 % (simplifypath(pycompat.sysstr(frame.path)), frame.lineno),
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(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43053
diff changeset
1059 sys.argv[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:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1083 assert False, b"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())