Mercurial > hg
annotate mercurial/statprof.py @ 43007:f1dffb37f27c
tests: suppress output from write()
Otherwise it is printed and the test fails with tons of output on
Python 3.
Differential Revision: https://phab.mercurial-scm.org/D6918
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Sun, 29 Sep 2019 12:19:45 -0700 |
parents | cde1c101ab8a |
children | 9a3be115fb78 |
rev | line source |
---|---|
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
1 #!/usr/bin/env python |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
2 ## statprof.py |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
3 ## Copyright (C) 2012 Bryan O'Sullivan <bos@serpentine.com> |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
4 ## Copyright (C) 2011 Alex Fraser <alex at phatcore dot com> |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
5 ## 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
|
6 ## Copyright (C) 2001 Rob Browning <rlb at defaultvalue dot org> |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
7 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
8 ## 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
|
9 ## 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
|
10 ## License as published by the Free Software Foundation; either |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
11 ## 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
|
12 ## |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
13 ## 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
|
14 ## but WITHOUT ANY WARRANTY; without even the implied warranty of |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
15 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
16 ## Lesser General Public License for more details. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
17 ## |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
18 ## 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
|
19 ## License along with this program; if not, contact: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
20 ## |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
21 ## Free Software Foundation Voice: +1-617-542-5942 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
22 ## 59 Temple Place - Suite 330 Fax: +1-617-542-2652 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
23 ## Boston, MA 02111-1307, USA gnu@gnu.org |
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 """ |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
26 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
|
27 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
|
28 also named statprof, available from guile-lib [0]. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
29 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
30 [0] http://wingolog.org/software/guile-lib/statprof/ |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
31 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
32 To start profiling, call statprof.start(): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
33 >>> start() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
34 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
35 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
|
36 >>> import test.pystone; test.pystone.pystones() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
37 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
38 Then stop the profiling and print out the results: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
39 >>> stop() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
40 >>> display() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
41 % cumulative self |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
42 time seconds seconds name |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
43 26.72 1.40 0.37 pystone.py:79:Proc0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
44 13.79 0.56 0.19 pystone.py:133:Proc1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
45 13.79 0.19 0.19 pystone.py:208:Proc8 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
46 10.34 0.16 0.14 pystone.py:229:Func2 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
47 6.90 0.10 0.10 pystone.py:45:__init__ |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
48 4.31 0.16 0.06 pystone.py:53:copy |
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 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
51 All of the numerical data is statistically approximate. In the |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
52 following column descriptions, and in all of statprof, "time" refers |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
53 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
|
54 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
55 % time |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
56 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
|
57 counting children). |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
58 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
59 cumulative seconds |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
60 The total number of seconds spent in the procedure, including |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
61 children. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
62 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
63 self seconds |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
64 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
|
65 counting children). |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
66 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
67 name |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
68 The name of the procedure. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
69 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
70 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
|
71 want to clear the collected data, call reset(): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
72 >>> reset() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
73 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
74 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
|
75 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
|
76 second: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
77 >>> reset(50) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
78 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
79 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
|
80 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
|
81 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
|
82 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
|
83 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
|
84 operations. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
85 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
86 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
|
87 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
|
88 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
|
89 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
90 Right now the profiler is quite simplistic. I cannot provide |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
91 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
|
92 table is pretty much all there is. Patches are welcome :-) |
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 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
95 Threading |
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 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
98 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
|
99 statprof only profiles the main thread. However because the time |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
100 reporting function uses per-process timers, the results can be |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
101 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
|
102 main thread's work patterns. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
103 """ |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
104 # no-check-code |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
105 from __future__ import absolute_import, division, print_function |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
106 |
30256
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
107 import collections |
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
108 import contextlib |
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
109 import getopt |
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
110 import inspect |
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
111 import json |
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
112 import os |
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
113 import signal |
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
114 import sys |
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
115 import threading |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
116 import time |
30256
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
117 |
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 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
126 __all__ = ['start', 'stop', 'reset', 'display', 'profile'] |
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 = { |
2864f8d3fcd6
py3: use raw strings for stack names
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40191
diff
changeset
|
129 r"util.py:check", |
2864f8d3fcd6
py3: use raw strings for stack names
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40191
diff
changeset
|
130 r"extensions.py:closure", |
2864f8d3fcd6
py3: use raw strings for stack names
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40191
diff
changeset
|
131 r"color.py:colorcmd", |
2864f8d3fcd6
py3: use raw strings for stack names
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40191
diff
changeset
|
132 r"dispatch.py:checkargs", |
2864f8d3fcd6
py3: use raw strings for stack names
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40191
diff
changeset
|
133 r"dispatch.py:<lambda>", |
2864f8d3fcd6
py3: use raw strings for stack names
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40191
diff
changeset
|
134 r"dispatch.py:_runcatch", |
2864f8d3fcd6
py3: use raw strings for stack names
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40191
diff
changeset
|
135 r"dispatch.py:_dispatch", |
2864f8d3fcd6
py3: use raw strings for stack names
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40191
diff
changeset
|
136 r"dispatch.py:_runcommand", |
2864f8d3fcd6
py3: use raw strings for stack names
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40191
diff
changeset
|
137 r"pager.py:pagecmd", |
2864f8d3fcd6
py3: use raw strings for stack names
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40191
diff
changeset
|
138 r"dispatch.py:run", |
2864f8d3fcd6
py3: use raw strings for stack names
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40191
diff
changeset
|
139 r"dispatch.py:dispatch", |
2864f8d3fcd6
py3: use raw strings for stack names
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40191
diff
changeset
|
140 r"dispatch.py:runcommand", |
2864f8d3fcd6
py3: use raw strings for stack names
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40191
diff
changeset
|
141 r"hg.py:<module>", |
2864f8d3fcd6
py3: use raw strings for stack names
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40191
diff
changeset
|
142 r"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 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
148 def clock(): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
149 times = os.times() |
38259
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
150 return (times[0] + times[1], times[4]) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
151 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
152 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
153 ########################################################################### |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
154 ## Collection data structures |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
155 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
156 class ProfileState(object): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
157 def __init__(self, frequency=None): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
158 self.reset(frequency) |
38260
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
159 self.track = 'cpu' |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
160 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
161 def reset(self, frequency=None): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
162 # total so far |
38259
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
163 self.accumulated_time = (0.0, 0.0) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
164 # start_time when timer is active |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
165 self.last_start_time = None |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
166 # a float |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
167 if frequency: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
168 self.sample_interval = 1.0 / frequency |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
169 elif not hasattr(self, 'sample_interval'): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
170 # default to 1000 Hz |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
171 self.sample_interval = 1.0 / 1000.0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
172 else: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
173 # leave the frequency as it was |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
174 pass |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
175 self.remaining_prof_time = None |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
176 # for user start/stop nesting |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
177 self.profile_level = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
178 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
179 self.samples = [] |
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 def accumulate_time(self, stop_time): |
38259
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
182 increment = ( |
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
183 stop_time[0] - self.last_start_time[0], |
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
184 stop_time[1] - self.last_start_time[1], |
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
185 ) |
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
186 self.accumulated_time = ( |
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
187 self.accumulated_time[0] + increment[0], |
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
188 self.accumulated_time[1] + increment[1], |
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
189 ) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
190 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
191 def seconds_per_sample(self): |
38260
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
192 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
|
193 |
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
194 @property |
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
195 def timeidx(self): |
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
196 if self.track == 'real': |
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
197 return 1 |
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
198 return 0 |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
199 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
200 state = ProfileState() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
201 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
202 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
203 class CodeSite(object): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
204 cache = {} |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
205 |
41831
ae189674bdad
global: use raw strings for __slots__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
41365
diff
changeset
|
206 __slots__ = (r'path', r'lineno', r'function', r'source') |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
207 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
208 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
|
209 assert isinstance(path, bytes) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
210 self.path = path |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
211 self.lineno = lineno |
40484
93501a5fd62b
statprof: add a couple of asserts to avoid storing unicodes
Augie Fackler <augie@google.com>
parents:
40385
diff
changeset
|
212 assert isinstance(function, bytes) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
213 self.function = function |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
214 self.source = None |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
215 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
216 def __eq__(self, other): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
217 try: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
218 return (self.lineno == other.lineno and |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
219 self.path == other.path) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
220 except: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
221 return False |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
222 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
223 def __hash__(self): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
224 return hash((self.lineno, self.path)) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
225 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
226 @classmethod |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
227 def get(cls, path, lineno, function): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
228 k = (path, lineno) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
229 try: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
230 return cls.cache[k] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
231 except KeyError: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
232 v = cls(path, lineno, function) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
233 cls.cache[k] = v |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
234 return v |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
235 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
236 def getsource(self, length): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
237 if self.source is None: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
238 lineno = self.lineno - 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
239 try: |
42834
c085cb134b9e
statprof: use context manager when reading source from file
Martin von Zweigbergk <martinvonz@google.com>
parents:
42833
diff
changeset
|
240 with open(self.path, 'rb') as fp: |
c085cb134b9e
statprof: use context manager when reading source from file
Martin von Zweigbergk <martinvonz@google.com>
parents:
42833
diff
changeset
|
241 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
|
242 if i == lineno: |
c085cb134b9e
statprof: use context manager when reading source from file
Martin von Zweigbergk <martinvonz@google.com>
parents:
42833
diff
changeset
|
243 self.source = line.strip() |
c085cb134b9e
statprof: use context manager when reading source from file
Martin von Zweigbergk <martinvonz@google.com>
parents:
42833
diff
changeset
|
244 break |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
245 except: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
246 pass |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
247 if self.source is None: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
248 self.source = '' |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
249 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
250 source = self.source |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
251 if len(source) > length: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
252 source = source[:(length - 3)] + "..." |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
253 return source |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
254 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
255 def filename(self): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
256 return os.path.basename(self.path) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
257 |
40385
cc4586749c8c
statprof: fix overflow while skipping boilerplate parts
Yuya Nishihara <yuya@tcha.org>
parents:
40384
diff
changeset
|
258 def skipname(self): |
cc4586749c8c
statprof: fix overflow while skipping boilerplate parts
Yuya Nishihara <yuya@tcha.org>
parents:
40384
diff
changeset
|
259 return r'%s:%s' % (self.filename(), self.function) |
cc4586749c8c
statprof: fix overflow while skipping boilerplate parts
Yuya Nishihara <yuya@tcha.org>
parents:
40384
diff
changeset
|
260 |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
261 class Sample(object): |
41831
ae189674bdad
global: use raw strings for __slots__
Gregory Szorc <gregory.szorc@gmail.com>
parents:
41365
diff
changeset
|
262 __slots__ = (r'stack', r'time') |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
263 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
264 def __init__(self, stack, time): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
265 self.stack = stack |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
266 self.time = time |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
267 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
268 @classmethod |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
269 def from_frame(cls, frame, time): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
270 stack = [] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
271 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
272 while frame: |
40485
8664fdc1cfb3
statprof: clean up unicode/bytes a little
Augie Fackler <augie@google.com>
parents:
40484
diff
changeset
|
273 stack.append(CodeSite.get( |
8664fdc1cfb3
statprof: clean up unicode/bytes a little
Augie Fackler <augie@google.com>
parents:
40484
diff
changeset
|
274 pycompat.sysbytes(frame.f_code.co_filename), |
8664fdc1cfb3
statprof: clean up unicode/bytes a little
Augie Fackler <augie@google.com>
parents:
40484
diff
changeset
|
275 frame.f_lineno, |
8664fdc1cfb3
statprof: clean up unicode/bytes a little
Augie Fackler <augie@google.com>
parents:
40484
diff
changeset
|
276 pycompat.sysbytes(frame.f_code.co_name))) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
277 frame = frame.f_back |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
278 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
279 return Sample(stack, time) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
280 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
281 ########################################################################### |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
282 ## SIGPROF handler |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
283 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
284 def profile_signal_handler(signum, frame): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
285 if state.profile_level > 0: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
286 now = clock() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
287 state.accumulate_time(now) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
288 |
38260
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
289 timestamp = state.accumulated_time[state.timeidx] |
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
290 state.samples.append(Sample.from_frame(frame, timestamp)) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
291 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
292 signal.setitimer(signal.ITIMER_PROF, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
293 state.sample_interval, 0.0) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
294 state.last_start_time = now |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
295 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
296 stopthread = threading.Event() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
297 def samplerthread(tid): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
298 while not stopthread.is_set(): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
299 now = clock() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
300 state.accumulate_time(now) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
301 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
302 frame = sys._current_frames()[tid] |
38260
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
303 |
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
304 timestamp = state.accumulated_time[state.timeidx] |
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
305 state.samples.append(Sample.from_frame(frame, timestamp)) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
306 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
307 state.last_start_time = now |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
308 time.sleep(state.sample_interval) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
309 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
310 stopthread.clear() |
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 ########################################################################### |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
313 ## Profiling API |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
314 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
315 def is_active(): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
316 return state.profile_level > 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
317 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
318 lastmechanism = None |
38260
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
319 def start(mechanism='thread', track='cpu'): |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
320 '''Install the profiling signal handler, and start profiling.''' |
38260
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
321 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
|
322 state.profile_level += 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
323 if state.profile_level == 1: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
324 state.last_start_time = clock() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
325 rpt = state.remaining_prof_time |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
326 state.remaining_prof_time = None |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
327 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
328 global lastmechanism |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
329 lastmechanism = mechanism |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
330 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
331 if mechanism == 'signal': |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
332 signal.signal(signal.SIGPROF, profile_signal_handler) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
333 signal.setitimer(signal.ITIMER_PROF, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
334 rpt or state.sample_interval, 0.0) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
335 elif mechanism == 'thread': |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
336 frame = inspect.currentframe() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
337 tid = [k for k, f in sys._current_frames().items() if f == frame][0] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
338 state.thread = threading.Thread(target=samplerthread, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
339 args=(tid,), name="samplerthread") |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
340 state.thread.start() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
341 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
342 def stop(): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
343 '''Stop profiling, and uninstall the profiling signal handler.''' |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
344 state.profile_level -= 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
345 if state.profile_level == 0: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
346 if lastmechanism == 'signal': |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
347 rpt = signal.setitimer(signal.ITIMER_PROF, 0.0, 0.0) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
348 signal.signal(signal.SIGPROF, signal.SIG_IGN) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
349 state.remaining_prof_time = rpt[0] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
350 elif lastmechanism == 'thread': |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
351 stopthread.set() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
352 state.thread.join() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
353 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
354 state.accumulate_time(clock()) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
355 state.last_start_time = None |
30637
344e68882cd3
py3: replace os.environ with encoding.environ (part 4 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30578
diff
changeset
|
356 statprofpath = encoding.environ.get('STATPROF_DEST') |
30255
f42cd5434cc2
statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30254
diff
changeset
|
357 if statprofpath: |
f42cd5434cc2
statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30254
diff
changeset
|
358 save_data(statprofpath) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
359 |
30299
1e5346313963
statprof: return state from stop()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30258
diff
changeset
|
360 return state |
1e5346313963
statprof: return state from stop()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30258
diff
changeset
|
361 |
30255
f42cd5434cc2
statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30254
diff
changeset
|
362 def save_data(path): |
f42cd5434cc2
statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30254
diff
changeset
|
363 with open(path, 'w+') as file: |
38274
99188a7c8717
statprof: fix save and load
Boris Feld <boris.feld@octobus.net>
parents:
38260
diff
changeset
|
364 file.write("%f %f\n" % state.accumulated_time) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
365 for sample in state.samples: |
40197
113adb1b3f24
py3: use %d in a few places
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40196
diff
changeset
|
366 time = sample.time |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
367 stack = sample.stack |
40201
7df42042636d
py3: sprinkle statprof.py with utf-8 encoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40199
diff
changeset
|
368 sites = ['\1'.join([s.path, b'%d' % s.lineno, s.function]) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
369 for s in stack] |
40197
113adb1b3f24
py3: use %d in a few places
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40196
diff
changeset
|
370 file.write("%d\0%s\n" % (time, '\0'.join(sites))) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
371 |
30255
f42cd5434cc2
statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30254
diff
changeset
|
372 def load_data(path): |
40485
8664fdc1cfb3
statprof: clean up unicode/bytes a little
Augie Fackler <augie@google.com>
parents:
40484
diff
changeset
|
373 lines = open(path, 'rb').read().splitlines() |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
374 |
38274
99188a7c8717
statprof: fix save and load
Boris Feld <boris.feld@octobus.net>
parents:
38260
diff
changeset
|
375 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
|
376 state.samples = [] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
377 for line in lines[1:]: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
378 parts = line.split('\0') |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
379 time = float(parts[0]) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
380 rawsites = parts[1:] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
381 sites = [] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
382 for rawsite in rawsites: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
383 siteparts = rawsite.split('\1') |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
384 sites.append(CodeSite.get(siteparts[0], int(siteparts[1]), |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
385 siteparts[2])) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
386 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
387 state.samples.append(Sample(sites, time)) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
388 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
389 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
390 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
391 def reset(frequency=None): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
392 '''Clear out the state of the profiler. Do not call while the |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
393 profiler is running. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
394 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
395 The optional frequency argument specifies the number of samples to |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
396 collect per second.''' |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
397 assert state.profile_level == 0, "Can't reset() while statprof is running" |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
398 CodeSite.cache.clear() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
399 state.reset(frequency) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
400 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
401 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
402 @contextmanager |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
403 def profile(): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
404 start() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
405 try: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
406 yield |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
407 finally: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
408 stop() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
409 display() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
410 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
411 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
412 ########################################################################### |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
413 ## Reporting API |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
414 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
415 class SiteStats(object): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
416 def __init__(self, site): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
417 self.site = site |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
418 self.selfcount = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
419 self.totalcount = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
420 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
421 def addself(self): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
422 self.selfcount += 1 |
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 def addtotal(self): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
425 self.totalcount += 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
426 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
427 def selfpercent(self): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
428 return self.selfcount / len(state.samples) * 100 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
429 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
430 def totalpercent(self): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
431 return self.totalcount / len(state.samples) * 100 |
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 def selfseconds(self): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
434 return self.selfcount * state.seconds_per_sample() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
435 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
436 def totalseconds(self): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
437 return self.totalcount * state.seconds_per_sample() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
438 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
439 @classmethod |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
440 def buildstats(cls, samples): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
441 stats = {} |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
442 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
443 for sample in samples: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
444 for i, site in enumerate(sample.stack): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
445 sitestat = stats.get(site) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
446 if not sitestat: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
447 sitestat = SiteStats(site) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
448 stats[site] = sitestat |
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 sitestat.addtotal() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
451 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
452 if i == 0: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
453 sitestat.addself() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
454 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
455 return [s for s in stats.itervalues()] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
456 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
457 class DisplayFormats: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
458 ByLine = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
459 ByMethod = 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
460 AboutMethod = 2 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
461 Hotpath = 3 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
462 FlameGraph = 4 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
463 Json = 5 |
30929
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
464 Chrome = 6 |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
465 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
466 def display(fp=None, format=3, data=None, **kwargs): |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
467 '''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
|
468 if data is None: |
3c569172848d
statprof: small if cleanup
Boris Feld <boris.feld@octobus.net>
parents:
38274
diff
changeset
|
469 data = state |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
470 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
471 if fp is None: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
472 import sys |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
473 fp = sys.stdout |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
474 if len(data.samples) == 0: |
40198
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
475 fp.write(b'No samples recorded.\n') |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
476 return |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
477 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
478 if format == DisplayFormats.ByLine: |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
479 display_by_line(data, fp) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
480 elif format == DisplayFormats.ByMethod: |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
481 display_by_method(data, fp) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
482 elif format == DisplayFormats.AboutMethod: |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
483 display_about_method(data, fp, **kwargs) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
484 elif format == DisplayFormats.Hotpath: |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
485 display_hotpath(data, fp, **kwargs) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
486 elif format == DisplayFormats.FlameGraph: |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
487 write_to_flame(data, fp, **kwargs) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
488 elif format == DisplayFormats.Json: |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
489 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
|
490 elif format == DisplayFormats.Chrome: |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
491 write_to_chrome(data, fp, **kwargs) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
492 else: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
493 raise Exception("Invalid display format") |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
494 |
30929
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
495 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
|
496 fp.write(b'---\n') |
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
497 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
|
498 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
|
499 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
500 def display_by_line(data, fp): |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
501 '''Print the profiler data with each sample line represented |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
502 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
|
503 stats = SiteStats.buildstats(data.samples) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
504 stats.sort(reverse=True, key=lambda x: x.selfseconds()) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
505 |
40198
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
506 fp.write(b'%5.5s %10.10s %7.7s %-8.8s\n' % ( |
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
507 b'% ', b'cumulative', b'self', b'')) |
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
508 fp.write(b'%5.5s %9.9s %8.8s %-8.8s\n' % ( |
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
509 b"time", b"seconds", b"seconds", b"name")) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
510 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
511 for stat in stats: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
512 site = stat.site |
40485
8664fdc1cfb3
statprof: clean up unicode/bytes a little
Augie Fackler <augie@google.com>
parents:
40484
diff
changeset
|
513 sitelabel = '%s:%d:%s' % (site.filename(), |
40201
7df42042636d
py3: sprinkle statprof.py with utf-8 encoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40199
diff
changeset
|
514 site.lineno, |
40485
8664fdc1cfb3
statprof: clean up unicode/bytes a little
Augie Fackler <augie@google.com>
parents:
40484
diff
changeset
|
515 site.function) |
40198
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
516 fp.write(b'%6.2f %9.2f %9.2f %s\n' % ( |
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
517 stat.selfpercent(), stat.totalseconds(), |
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
518 stat.selfseconds(), sitelabel)) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
519 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
520 def display_by_method(data, fp): |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
521 '''Print the profiler data with each sample function represented |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
522 as one row in a table. Important lines within that function are |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
523 output as nested rows. Sorted by self-time per line.''' |
40198
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
524 fp.write(b'%5.5s %10.10s %7.7s %-8.8s\n' % |
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
525 ('% ', 'cumulative', 'self', '')) |
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
526 fp.write(b'%5.5s %9.9s %8.8s %-8.8s\n' % |
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
527 ("time", "seconds", "seconds", "name")) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
528 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
529 stats = SiteStats.buildstats(data.samples) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
530 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
531 grouped = defaultdict(list) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
532 for stat in stats: |
40485
8664fdc1cfb3
statprof: clean up unicode/bytes a little
Augie Fackler <augie@google.com>
parents:
40484
diff
changeset
|
533 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
|
534 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
535 # compute sums for each function |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
536 functiondata = [] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
537 for fname, sitestats in grouped.iteritems(): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
538 total_cum_sec = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
539 total_self_sec = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
540 total_percent = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
541 for stat in sitestats: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
542 total_cum_sec += stat.totalseconds() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
543 total_self_sec += stat.selfseconds() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
544 total_percent += stat.selfpercent() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
545 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
546 functiondata.append((fname, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
547 total_cum_sec, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
548 total_self_sec, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
549 total_percent, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
550 sitestats)) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
551 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
552 # sort by total self sec |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
553 functiondata.sort(reverse=True, key=lambda x: x[2]) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
554 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
555 for function in functiondata: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
556 if function[3] < 0.05: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
557 continue |
40198
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
558 fp.write(b'%6.2f %9.2f %9.2f %s\n' % ( |
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
559 function[3], # total percent |
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
560 function[1], # total cum sec |
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
561 function[2], # total self sec |
40485
8664fdc1cfb3
statprof: clean up unicode/bytes a little
Augie Fackler <augie@google.com>
parents:
40484
diff
changeset
|
562 function[0])) # file:function |
40198
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
563 |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
564 function[4].sort(reverse=True, key=lambda i: i.selfseconds()) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
565 for stat in function[4]: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
566 # only show line numbers for significant locations (>1% time spent) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
567 if stat.selfpercent() > 1: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
568 source = stat.site.getsource(25) |
40201
7df42042636d
py3: sprinkle statprof.py with utf-8 encoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40199
diff
changeset
|
569 if sys.version_info.major >= 3 and not isinstance(source, bytes): |
7df42042636d
py3: sprinkle statprof.py with utf-8 encoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40199
diff
changeset
|
570 source = pycompat.bytestr(source) |
7df42042636d
py3: sprinkle statprof.py with utf-8 encoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40199
diff
changeset
|
571 |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
572 stattuple = (stat.selfpercent(), stat.selfseconds(), |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
573 stat.site.lineno, source) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
574 |
40198
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
575 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
|
576 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
577 def display_about_method(data, fp, function=None, **kwargs): |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
578 if function is None: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
579 raise Exception("Invalid function") |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
580 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
581 filename = None |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
582 if ':' in function: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
583 filename, function = function.split(':') |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
584 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
585 relevant_samples = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
586 parents = {} |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
587 children = {} |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
588 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
589 for sample in data.samples: |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
590 for i, site in enumerate(sample.stack): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
591 if site.function == function and (not filename |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
592 or site.filename() == filename): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
593 relevant_samples += 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
594 if i != len(sample.stack) - 1: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
595 parent = sample.stack[i + 1] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
596 if parent in parents: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
597 parents[parent] = parents[parent] + 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
598 else: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
599 parents[parent] = 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
600 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
601 if site in children: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
602 children[site] = children[site] + 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
603 else: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
604 children[site] = 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
605 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
606 parents = [(parent, count) for parent, count in parents.iteritems()] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
607 parents.sort(reverse=True, key=lambda x: x[1]) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
608 for parent, count in parents: |
40198
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
609 fp.write(b'%6.2f%% %s:%s line %s: %s\n' % |
40201
7df42042636d
py3: sprinkle statprof.py with utf-8 encoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40199
diff
changeset
|
610 (count / relevant_samples * 100, |
7df42042636d
py3: sprinkle statprof.py with utf-8 encoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40199
diff
changeset
|
611 pycompat.fsencode(parent.filename()), |
7df42042636d
py3: sprinkle statprof.py with utf-8 encoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40199
diff
changeset
|
612 pycompat.sysbytes(parent.function), |
7df42042636d
py3: sprinkle statprof.py with utf-8 encoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40199
diff
changeset
|
613 parent.lineno, |
7df42042636d
py3: sprinkle statprof.py with utf-8 encoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40199
diff
changeset
|
614 pycompat.sysbytes(parent.getsource(50)))) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
615 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
616 stats = SiteStats.buildstats(data.samples) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
617 stats = [s for s in stats |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
618 if s.site.function == function and |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
619 (not filename or s.site.filename() == filename)] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
620 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
621 total_cum_sec = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
622 total_self_sec = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
623 total_self_percent = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
624 total_cum_percent = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
625 for stat in stats: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
626 total_cum_sec += stat.totalseconds() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
627 total_self_sec += stat.selfseconds() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
628 total_self_percent += stat.selfpercent() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
629 total_cum_percent += stat.totalpercent() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
630 |
40198
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
631 fp.write( |
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
632 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
|
633 % ( |
40201
7df42042636d
py3: sprinkle statprof.py with utf-8 encoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40199
diff
changeset
|
634 pycompat.sysbytes(filename or '___'), |
7df42042636d
py3: sprinkle statprof.py with utf-8 encoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40199
diff
changeset
|
635 pycompat.sysbytes(function), |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
636 total_cum_sec, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
637 total_cum_percent, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
638 total_self_sec, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
639 total_self_percent |
40198
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
640 )) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
641 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
642 children = [(child, count) for child, count in children.iteritems()] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
643 children.sort(reverse=True, key=lambda x: x[1]) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
644 for child, count in children: |
40198
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
645 fp.write(b' %6.2f%% line %s: %s\n' % |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
646 (count / relevant_samples * 100, child.lineno, |
40201
7df42042636d
py3: sprinkle statprof.py with utf-8 encoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40199
diff
changeset
|
647 pycompat.sysbytes(child.getsource(50)))) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
648 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
649 def display_hotpath(data, fp, limit=0.05, **kwargs): |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
650 class HotNode(object): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
651 def __init__(self, site): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
652 self.site = site |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
653 self.count = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
654 self.children = {} |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
655 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
656 def add(self, stack, time): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
657 self.count += time |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
658 site = stack[0] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
659 child = self.children.get(site) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
660 if not child: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
661 child = HotNode(site) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
662 self.children[site] = child |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
663 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
664 if len(stack) > 1: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
665 i = 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
666 # 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
|
667 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
|
668 i += 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
669 if i < len(stack): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
670 child.add(stack[i:], time) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
671 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
672 root = HotNode(None) |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
673 lasttime = data.samples[0].time |
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
674 for sample in data.samples: |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
675 root.add(sample.stack[::-1], sample.time - lasttime) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
676 lasttime = sample.time |
42423
0ae593e791fb
profiling: show actual time spent in hotpath display
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
41831
diff
changeset
|
677 showtime = kwargs.get(r'showtime', True) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
678 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
679 def _write(node, depth, multiple_siblings): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
680 site = node.site |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
681 visiblechildren = [c for c in node.children.itervalues() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
682 if c.count >= (limit * root.count)] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
683 if site: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
684 indent = depth * 2 - 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
685 filename = '' |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
686 function = '' |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
687 if len(node.children) > 0: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
688 childsite = list(node.children.itervalues())[0].site |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
689 filename = (childsite.filename() + ':').ljust(15) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
690 function = childsite.function |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
691 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
692 # lots of string formatting |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
693 listpattern = ''.ljust(indent) +\ |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
694 ('\\' if multiple_siblings else '|') +\ |
42423
0ae593e791fb
profiling: show actual time spent in hotpath display
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
41831
diff
changeset
|
695 ' %4.1f%%' +\ |
0ae593e791fb
profiling: show actual time spent in hotpath display
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
41831
diff
changeset
|
696 (' %5.2fs' % node.count if showtime else '') +\ |
0ae593e791fb
profiling: show actual time spent in hotpath display
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents:
41831
diff
changeset
|
697 ' %s %s' |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
698 liststring = listpattern % (node.count / root.count * 100, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
699 filename, function) |
40485
8664fdc1cfb3
statprof: clean up unicode/bytes a little
Augie Fackler <augie@google.com>
parents:
40484
diff
changeset
|
700 codepattern = '%' + ('%d' % (55 - len(liststring))) + 's %d: %s' |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
701 codestring = codepattern % ('line', site.lineno, site.getsource(30)) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
702 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
703 finalstring = liststring + codestring |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
704 childrensamples = sum([c.count for c in node.children.itervalues()]) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
705 # 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
|
706 if node.count - childrensamples > (0.1 * root.count): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
707 finalstring = '\033[91m' + finalstring + '\033[0m' |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
708 # Make frames that didn't actually perform work dark grey |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
709 elif node.count - childrensamples == 0: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
710 finalstring = '\033[90m' + finalstring + '\033[0m' |
40384
fc4c598dd4a0
statprof: fix indent level of fp.write() (issue6004)
Yuya Nishihara <yuya@tcha.org>
parents:
40381
diff
changeset
|
711 fp.write(finalstring + b'\n') |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
712 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
713 newdepth = depth |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
714 if len(visiblechildren) > 1 or multiple_siblings: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
715 newdepth += 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
716 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
717 visiblechildren.sort(reverse=True, key=lambda x: x.count) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
718 for child in visiblechildren: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
719 _write(child, newdepth, len(visiblechildren) > 1) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
720 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
721 if root.count > 0: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
722 _write(root, 0, False) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
723 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
724 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
|
725 if scriptpath is None: |
30637
344e68882cd3
py3: replace os.environ with encoding.environ (part 4 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30578
diff
changeset
|
726 scriptpath = encoding.environ['HOME'] + '/flamegraph.pl' |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
727 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
|
728 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
|
729 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
|
730 return |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
731 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
732 lines = {} |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
733 for sample in data.samples: |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
734 sites = [s.function for s in sample.stack] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
735 sites.reverse() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
736 line = ';'.join(sites) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
737 if line in lines: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
738 lines[line] = lines[line] + 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
739 else: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
740 lines[line] = 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
741 |
42835
db6d7cbda80b
statprof: use context manager for file when writing flame graph
Martin von Zweigbergk <martinvonz@google.com>
parents:
42834
diff
changeset
|
742 fd, path = pycompat.mkstemp() |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
743 |
42835
db6d7cbda80b
statprof: use context manager for file when writing flame graph
Martin von Zweigbergk <martinvonz@google.com>
parents:
42834
diff
changeset
|
744 with open(path, "w+") as file: |
db6d7cbda80b
statprof: use context manager for file when writing flame graph
Martin von Zweigbergk <martinvonz@google.com>
parents:
42834
diff
changeset
|
745 for line, count in lines.iteritems(): |
db6d7cbda80b
statprof: use context manager for file when writing flame graph
Martin von Zweigbergk <martinvonz@google.com>
parents:
42834
diff
changeset
|
746 file.write("%s %d\n" % (line, count)) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
747 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
748 if outputfile is None: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
749 outputfile = '~/flamegraph.svg' |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
750 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
751 os.system("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
|
752 fp.write(b'Written to %s\n' % outputfile) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
753 |
30928
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
754 _pathcache = {} |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
755 def simplifypath(path): |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
756 '''Attempt to make the path to a Python module easier to read by |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
757 removing whatever part of the Python search path it was found |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
758 on.''' |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
759 |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
760 if path in _pathcache: |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
761 return _pathcache[path] |
42837
cde1c101ab8a
py3: make statprof's chrome output work
Martin von Zweigbergk <martinvonz@google.com>
parents:
42836
diff
changeset
|
762 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
|
763 for p in [hgpath] + sys.path: |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
764 prefix = p + os.sep |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
765 if path.startswith(prefix): |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
766 path = path[len(prefix):] |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
767 break |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
768 _pathcache[path] = path |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
769 return path |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
770 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
771 def write_to_json(data, fp): |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
772 samples = [] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
773 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
774 for sample in data.samples: |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
775 stack = [] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
776 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
777 for frame in sample.stack: |
40485
8664fdc1cfb3
statprof: clean up unicode/bytes a little
Augie Fackler <augie@google.com>
parents:
40484
diff
changeset
|
778 stack.append( |
8664fdc1cfb3
statprof: clean up unicode/bytes a little
Augie Fackler <augie@google.com>
parents:
40484
diff
changeset
|
779 (pycompat.sysstr(frame.path), |
8664fdc1cfb3
statprof: clean up unicode/bytes a little
Augie Fackler <augie@google.com>
parents:
40484
diff
changeset
|
780 frame.lineno, |
8664fdc1cfb3
statprof: clean up unicode/bytes a little
Augie Fackler <augie@google.com>
parents:
40484
diff
changeset
|
781 pycompat.sysstr(frame.function))) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
782 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
783 samples.append((sample.time, stack)) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
784 |
40191
4b7eb862692e
py3: encode json output to bytes and use write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39092
diff
changeset
|
785 data = json.dumps(samples) |
4b7eb862692e
py3: encode json output to bytes and use write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39092
diff
changeset
|
786 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
|
787 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
|
788 |
4b7eb862692e
py3: encode json output to bytes and use write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39092
diff
changeset
|
789 fp.write(data) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
790 |
30929
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
791 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
|
792 samples = [] |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
793 laststack = collections.deque() |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
794 lastseen = collections.deque() |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
795 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
796 # 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
|
797 # 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
|
798 # 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
|
799 stack2id = {} |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
800 id2stack = [] # will eventually be rendered |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
801 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
802 def stackid(stack): |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
803 if not stack: |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
804 return |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
805 if stack in stack2id: |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
806 return stack2id[stack] |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
807 parent = stackid(stack[1:]) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
808 myid = len(stack2id) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
809 stack2id[stack] = myid |
42837
cde1c101ab8a
py3: make statprof's chrome output work
Martin von Zweigbergk <martinvonz@google.com>
parents:
42836
diff
changeset
|
810 id2stack.append(dict(category=stack[0][0], name=r'%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
|
811 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
|
812 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
|
813 return myid |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
814 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
815 # 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
|
816 # 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
|
817 # 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
|
818 # 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
|
819 # millisecond in length. |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
820 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
821 clamp = 0.001 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
822 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
823 # 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
|
824 # 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
|
825 # |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
826 # * 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
|
827 # 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
|
828 # |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
829 # * 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
|
830 # 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
|
831 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
832 blacklist = set() |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
833 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
|
834 minthreshold = totaltime * minthreshold |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
835 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
|
836 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
837 def poplast(): |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
838 oldsid = stackid(tuple(laststack)) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
839 oldcat, oldfunc = laststack.popleft() |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
840 oldtime, oldidx = lastseen.popleft() |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
841 duration = sample.time - oldtime |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
842 if minthreshold <= duration <= maxthreshold: |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
843 # 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
|
844 sampletime = max(oldtime + clamp, sample.time) |
42837
cde1c101ab8a
py3: make statprof's chrome output work
Martin von Zweigbergk <martinvonz@google.com>
parents:
42836
diff
changeset
|
845 samples.append(dict(ph=r'E', name=oldfunc, cat=oldcat, sf=oldsid, |
30929
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
846 ts=sampletime*1e6, pid=0)) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
847 else: |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
848 blacklist.add(oldidx) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
849 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
850 # 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
|
851 # 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
|
852 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
853 for sample in data.samples: |
42837
cde1c101ab8a
py3: make statprof's chrome output work
Martin von Zweigbergk <martinvonz@google.com>
parents:
42836
diff
changeset
|
854 stack = tuple(((r'%s:%d' % (simplifypath(pycompat.sysstr(frame.path)), |
cde1c101ab8a
py3: make statprof's chrome output work
Martin von Zweigbergk <martinvonz@google.com>
parents:
42836
diff
changeset
|
855 frame.lineno), |
cde1c101ab8a
py3: make statprof's chrome output work
Martin von Zweigbergk <martinvonz@google.com>
parents:
42836
diff
changeset
|
856 pycompat.sysstr(frame.function)) |
cde1c101ab8a
py3: make statprof's chrome output work
Martin von Zweigbergk <martinvonz@google.com>
parents:
42836
diff
changeset
|
857 for frame in sample.stack)) |
30929
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
858 qstack = collections.deque(stack) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
859 if laststack == qstack: |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
860 continue |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
861 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
|
862 laststack.pop() |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
863 qstack.pop() |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
864 while laststack: |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
865 poplast() |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
866 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
|
867 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
|
868 laststack.appendleft(f) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
869 path, name = f |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
870 sid = stackid(tuple(laststack)) |
42837
cde1c101ab8a
py3: make statprof's chrome output work
Martin von Zweigbergk <martinvonz@google.com>
parents:
42836
diff
changeset
|
871 samples.append(dict(ph=r'B', name=name, cat=path, |
cde1c101ab8a
py3: make statprof's chrome output work
Martin von Zweigbergk <martinvonz@google.com>
parents:
42836
diff
changeset
|
872 ts=sample.time*1e6, sf=sid, pid=0)) |
30929
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
873 laststack = collections.deque(stack) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
874 while laststack: |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
875 poplast() |
42833
3f81d58aae25
statprof: clarify by naming tuple members while enumerate()'ing
Martin von Zweigbergk <martinvonz@google.com>
parents:
42423
diff
changeset
|
876 events = [sample for idx, sample in enumerate(samples) |
3f81d58aae25
statprof: clarify by naming tuple members while enumerate()'ing
Martin von Zweigbergk <martinvonz@google.com>
parents:
42423
diff
changeset
|
877 if idx not in blacklist] |
30929
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
878 frames = collections.OrderedDict((str(k), v) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
879 for (k,v) in enumerate(id2stack)) |
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
|
880 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
|
881 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
|
882 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
|
883 fp.write(data) |
30929
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
884 fp.write('\n') |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
885 |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
886 def printusage(): |
40198
9d3034348c4f
py3: switch from print(..., file=) to write()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40197
diff
changeset
|
887 print(r""" |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
888 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
|
889 the following forms: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
890 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
891 usage: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
892 hotpath [-l --limit percent] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
893 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
|
894 Red calls take over 10%% of the total time themselves. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
895 lines |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
896 Shows the actual sampled lines. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
897 functions |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
898 Shows the samples grouped by function. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
899 function [filename:]functionname |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
900 Shows the callers and callees of a particular function. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
901 flame [-s --script-path] [-o --output-file path] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
902 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
|
903 Requires that ~/flamegraph.pl exist. |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
904 (Specify alternate script path with --script-path.)""") |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
905 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
906 def main(argv=None): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
907 if argv is None: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
908 argv = sys.argv |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
909 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
910 if len(argv) == 1: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
911 printusage() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
912 return 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
913 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
914 displayargs = {} |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
915 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
916 optstart = 2 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
917 displayargs['function'] = None |
40199
b594db74dc13
py3: use raw strings in statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40198
diff
changeset
|
918 if argv[1] == r'hotpath': |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
919 displayargs['format'] = DisplayFormats.Hotpath |
40199
b594db74dc13
py3: use raw strings in statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40198
diff
changeset
|
920 elif argv[1] == r'lines': |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
921 displayargs['format'] = DisplayFormats.ByLine |
40199
b594db74dc13
py3: use raw strings in statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40198
diff
changeset
|
922 elif argv[1] == r'functions': |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
923 displayargs['format'] = DisplayFormats.ByMethod |
40199
b594db74dc13
py3: use raw strings in statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40198
diff
changeset
|
924 elif argv[1] == r'function': |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
925 displayargs['format'] = DisplayFormats.AboutMethod |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
926 displayargs['function'] = argv[2] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
927 optstart = 3 |
40199
b594db74dc13
py3: use raw strings in statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40198
diff
changeset
|
928 elif argv[1] == r'flame': |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
929 displayargs['format'] = DisplayFormats.FlameGraph |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
930 else: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
931 printusage() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
932 return 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
933 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
934 # process options |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
935 try: |
30578
c6ce11f2ee50
py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30568
diff
changeset
|
936 opts, args = pycompat.getoptb(sys.argv[optstart:], "hl:f:o:p:", |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
937 ["help", "limit=", "file=", "output-file=", "script-path="]) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
938 except getopt.error as msg: |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
939 print(msg) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
940 printusage() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
941 return 2 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
942 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
943 displayargs['limit'] = 0.05 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
944 path = None |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
945 for o, value in opts: |
40199
b594db74dc13
py3: use raw strings in statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40198
diff
changeset
|
946 if o in (r"-l", r"--limit"): |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
947 displayargs['limit'] = float(value) |
40199
b594db74dc13
py3: use raw strings in statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40198
diff
changeset
|
948 elif o in (r"-f", r"--file"): |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
949 path = value |
40199
b594db74dc13
py3: use raw strings in statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40198
diff
changeset
|
950 elif o in (r"-o", r"--output-file"): |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
951 displayargs['outputfile'] = value |
40199
b594db74dc13
py3: use raw strings in statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40198
diff
changeset
|
952 elif o in (r"-p", r"--script-path"): |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
953 displayargs['scriptpath'] = value |
40199
b594db74dc13
py3: use raw strings in statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40198
diff
changeset
|
954 elif o in (r"-h", r"help"): |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
955 printusage() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
956 return 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
957 else: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
958 assert False, "unhandled option %s" % o |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
959 |
30845
262c2be8ea5a
statprof: require input file
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30637
diff
changeset
|
960 if not path: |
40199
b594db74dc13
py3: use raw strings in statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40198
diff
changeset
|
961 print(r'must specify --file to load') |
30845
262c2be8ea5a
statprof: require input file
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30637
diff
changeset
|
962 return 1 |
262c2be8ea5a
statprof: require input file
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30637
diff
changeset
|
963 |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
964 load_data(path=path) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
965 |
35370
c5853c9a6545
py3: handle keyword arguments correctly in statprof.py
Pulkit Goyal <7895pulkit@gmail.com>
parents:
32291
diff
changeset
|
966 display(**pycompat.strkwargs(displayargs)) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
967 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
968 return 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
969 |
40199
b594db74dc13
py3: use raw strings in statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40198
diff
changeset
|
970 if __name__ == r"__main__": |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
971 sys.exit(main()) |