annotate mercurial/statprof.py @ 30576:541949a10a68

fancyopts: switch from fancyopts.getopt.* to getopt.* In the next patch, we will be creating a bytes version of getopt.getopt() and doing that will leave getopt as unused import in fancyopts. So before removing that there are instances in codebase where instead of importing getopt, we have used fancyopts.getopt. This patch will switch all those cases so that the next patch can remove the import of getopt from fancyopts without breaking things.
author Pulkit Goyal <7895pulkit@gmail.com>
date Tue, 06 Dec 2016 06:27:58 +0530
parents bb35fe8621f5
children c6ce11f2ee50
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1 #!/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 tempfile
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
116 import threading
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
117 import time
30256
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
118
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
119 defaultdict = collections.defaultdict
2ed0b3f9f79e statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30255
diff changeset
120 contextmanager = contextlib.contextmanager
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
121
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
122 __all__ = ['start', 'stop', 'reset', 'display', 'profile']
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
123
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
124 skips = set(["util.py:check", "extensions.py:closure",
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
125 "color.py:colorcmd", "dispatch.py:checkargs",
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
126 "dispatch.py:<lambda>", "dispatch.py:_runcatch",
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
127 "dispatch.py:_dispatch", "dispatch.py:_runcommand",
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
128 "pager.py:pagecmd", "dispatch.py:run",
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
129 "dispatch.py:dispatch", "dispatch.py:runcommand",
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
130 "hg.py:<module>", "evolve.py:warnobserrors",
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
131 ])
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
132
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
133 ###########################################################################
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
134 ## Utils
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
135
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
136 def clock():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
137 times = os.times()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
138 return times[0] + times[1]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
139
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
140
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
141 ###########################################################################
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
142 ## Collection data structures
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
143
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
144 class ProfileState(object):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
145 def __init__(self, frequency=None):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
146 self.reset(frequency)
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 reset(self, frequency=None):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
149 # total so far
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
150 self.accumulated_time = 0.0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
151 # start_time when timer is active
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
152 self.last_start_time = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
153 # a float
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
154 if frequency:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
155 self.sample_interval = 1.0 / frequency
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
156 elif not hasattr(self, 'sample_interval'):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
157 # default to 1000 Hz
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
158 self.sample_interval = 1.0 / 1000.0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
159 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
160 # leave the frequency as it was
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
161 pass
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
162 self.remaining_prof_time = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
163 # for user start/stop nesting
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
164 self.profile_level = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
165
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
166 self.samples = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
167
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
168 def accumulate_time(self, stop_time):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
169 self.accumulated_time += stop_time - self.last_start_time
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
170
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
171 def seconds_per_sample(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
172 return self.accumulated_time / len(self.samples)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
173
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
174 state = ProfileState()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
175
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
176
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
177 class CodeSite(object):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
178 cache = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
179
30568
bb35fe8621f5 py3: use unicodes in __slots__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30299
diff changeset
180 __slots__ = (u'path', u'lineno', u'function', u'source')
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
181
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
182 def __init__(self, path, lineno, function):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
183 self.path = path
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
184 self.lineno = lineno
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
185 self.function = function
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
186 self.source = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
187
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
188 def __eq__(self, other):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
189 try:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
190 return (self.lineno == other.lineno and
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
191 self.path == other.path)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
192 except:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
193 return False
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
194
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
195 def __hash__(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
196 return hash((self.lineno, self.path))
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
197
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
198 @classmethod
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
199 def get(cls, path, lineno, function):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
200 k = (path, lineno)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
201 try:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
202 return cls.cache[k]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
203 except KeyError:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
204 v = cls(path, lineno, function)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
205 cls.cache[k] = v
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
206 return v
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 getsource(self, length):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
209 if self.source is None:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
210 lineno = self.lineno - 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
211 fp = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
212 try:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
213 fp = open(self.path)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
214 for i, line in enumerate(fp):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
215 if i == lineno:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
216 self.source = line.strip()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
217 break
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
218 except:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
219 pass
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
220 finally:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
221 if fp:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
222 fp.close()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
223 if self.source is None:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
224 self.source = ''
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 source = self.source
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
227 if len(source) > length:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
228 source = source[:(length - 3)] + "..."
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
229 return source
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
230
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
231 def filename(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
232 return os.path.basename(self.path)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
233
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
234 class Sample(object):
30568
bb35fe8621f5 py3: use unicodes in __slots__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30299
diff changeset
235 __slots__ = (u'stack', u'time')
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
236
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
237 def __init__(self, stack, time):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
238 self.stack = stack
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
239 self.time = time
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
240
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
241 @classmethod
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
242 def from_frame(cls, frame, time):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
243 stack = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
244
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
245 while frame:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
246 stack.append(CodeSite.get(frame.f_code.co_filename, frame.f_lineno,
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
247 frame.f_code.co_name))
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
248 frame = frame.f_back
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 return Sample(stack, time)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
251
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
252 ###########################################################################
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
253 ## SIGPROF handler
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 profile_signal_handler(signum, frame):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
256 if state.profile_level > 0:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
257 now = clock()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
258 state.accumulate_time(now)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
259
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
260 state.samples.append(Sample.from_frame(frame, state.accumulated_time))
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
261
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
262 signal.setitimer(signal.ITIMER_PROF,
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
263 state.sample_interval, 0.0)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
264 state.last_start_time = now
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
265
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
266 stopthread = threading.Event()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
267 def samplerthread(tid):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
268 while not stopthread.is_set():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
269 now = clock()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
270 state.accumulate_time(now)
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 frame = sys._current_frames()[tid]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
273 state.samples.append(Sample.from_frame(frame, state.accumulated_time))
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
274
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
275 state.last_start_time = now
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
276 time.sleep(state.sample_interval)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
277
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
278 stopthread.clear()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
279
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
280 ###########################################################################
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
281 ## Profiling API
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
282
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
283 def is_active():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
284 return state.profile_level > 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
285
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
286 lastmechanism = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
287 def start(mechanism='thread'):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
288 '''Install the profiling signal handler, and start profiling.'''
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
289 state.profile_level += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
290 if state.profile_level == 1:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
291 state.last_start_time = clock()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
292 rpt = state.remaining_prof_time
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
293 state.remaining_prof_time = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
294
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
295 global lastmechanism
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
296 lastmechanism = mechanism
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
297
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
298 if mechanism == 'signal':
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
299 signal.signal(signal.SIGPROF, profile_signal_handler)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
300 signal.setitimer(signal.ITIMER_PROF,
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
301 rpt or state.sample_interval, 0.0)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
302 elif mechanism == 'thread':
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
303 frame = inspect.currentframe()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
304 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
305 state.thread = threading.Thread(target=samplerthread,
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
306 args=(tid,), name="samplerthread")
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
307 state.thread.start()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
308
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
309 def stop():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
310 '''Stop profiling, and uninstall the profiling signal handler.'''
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
311 state.profile_level -= 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
312 if state.profile_level == 0:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
313 if lastmechanism == 'signal':
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
314 rpt = signal.setitimer(signal.ITIMER_PROF, 0.0, 0.0)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
315 signal.signal(signal.SIGPROF, signal.SIG_IGN)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
316 state.remaining_prof_time = rpt[0]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
317 elif lastmechanism == 'thread':
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
318 stopthread.set()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
319 state.thread.join()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
320
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
321 state.accumulate_time(clock())
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
322 state.last_start_time = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
323 statprofpath = os.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
324 if statprofpath:
f42cd5434cc2 statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30254
diff changeset
325 save_data(statprofpath)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
326
30299
1e5346313963 statprof: return state from stop()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30258
diff changeset
327 return state
1e5346313963 statprof: return state from stop()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30258
diff changeset
328
30255
f42cd5434cc2 statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30254
diff changeset
329 def save_data(path):
f42cd5434cc2 statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30254
diff changeset
330 with open(path, 'w+') as file:
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
331 file.write(str(state.accumulated_time) + '\n')
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
332 for sample in state.samples:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
333 time = str(sample.time)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
334 stack = sample.stack
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
335 sites = ['\1'.join([s.path, str(s.lineno), s.function])
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
336 for s in stack]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
337 file.write(time + '\0' + '\0'.join(sites) + '\n')
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
338
30255
f42cd5434cc2 statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30254
diff changeset
339 def load_data(path):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
340 lines = open(path, 'r').read().splitlines()
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 state.accumulated_time = float(lines[0])
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
343 state.samples = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
344 for line in lines[1:]:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
345 parts = line.split('\0')
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
346 time = float(parts[0])
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
347 rawsites = parts[1:]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
348 sites = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
349 for rawsite in rawsites:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
350 siteparts = rawsite.split('\1')
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
351 sites.append(CodeSite.get(siteparts[0], int(siteparts[1]),
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
352 siteparts[2]))
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.samples.append(Sample(sites, time))
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
355
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
356
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
357
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
358 def reset(frequency=None):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
359 '''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
360 profiler is running.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
361
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
362 The optional frequency argument specifies the number of samples to
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
363 collect per second.'''
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
364 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
365 CodeSite.cache.clear()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
366 state.reset(frequency)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
367
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
368
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
369 @contextmanager
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
370 def profile():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
371 start()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
372 try:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
373 yield
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
374 finally:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
375 stop()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
376 display()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
377
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
378
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
379 ###########################################################################
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
380 ## Reporting API
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
381
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
382 class SiteStats(object):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
383 def __init__(self, site):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
384 self.site = site
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
385 self.selfcount = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
386 self.totalcount = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
387
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
388 def addself(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
389 self.selfcount += 1
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 addtotal(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
392 self.totalcount += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
393
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
394 def selfpercent(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
395 return self.selfcount / len(state.samples) * 100
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
396
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
397 def totalpercent(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
398 return self.totalcount / len(state.samples) * 100
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
399
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
400 def selfseconds(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
401 return self.selfcount * state.seconds_per_sample()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
402
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
403 def totalseconds(self):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
404 return self.totalcount * state.seconds_per_sample()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
405
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
406 @classmethod
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
407 def buildstats(cls, samples):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
408 stats = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
409
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
410 for sample in samples:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
411 for i, site in enumerate(sample.stack):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
412 sitestat = stats.get(site)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
413 if not sitestat:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
414 sitestat = SiteStats(site)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
415 stats[site] = sitestat
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
416
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
417 sitestat.addtotal()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
418
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
419 if i == 0:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
420 sitestat.addself()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
421
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
422 return [s for s in stats.itervalues()]
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 class DisplayFormats:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
425 ByLine = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
426 ByMethod = 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
427 AboutMethod = 2
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
428 Hotpath = 3
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
429 FlameGraph = 4
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
430 Json = 5
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
431
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
432 def display(fp=None, format=3, data=None, **kwargs):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
433 '''Print statistics, either to stdout or the given file object.'''
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
434 data = data or state
30253
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 if fp is None:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
437 import sys
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
438 fp = sys.stdout
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
439 if len(data.samples) == 0:
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
440 print('No samples recorded.', file=fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
441 return
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 if format == DisplayFormats.ByLine:
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
444 display_by_line(data, fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
445 elif format == DisplayFormats.ByMethod:
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
446 display_by_method(data, fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
447 elif format == DisplayFormats.AboutMethod:
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
448 display_about_method(data, fp, **kwargs)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
449 elif format == DisplayFormats.Hotpath:
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
450 display_hotpath(data, fp, **kwargs)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
451 elif format == DisplayFormats.FlameGraph:
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
452 write_to_flame(data, fp, **kwargs)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
453 elif format == DisplayFormats.Json:
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
454 write_to_json(data, fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
455 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
456 raise Exception("Invalid display format")
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
457
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
458 if format != DisplayFormats.Json:
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
459 print('---', file=fp)
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
460 print('Sample count: %d' % len(data.samples), file=fp)
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
461 print('Total time: %f seconds' % data.accumulated_time, file=fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
462
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
463 def display_by_line(data, fp):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
464 '''Print the profiler data with each sample line represented
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
465 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
466 stats = SiteStats.buildstats(data.samples)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
467 stats.sort(reverse=True, key=lambda x: x.selfseconds())
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
468
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
469 print('%5.5s %10.10s %7.7s %-8.8s' %
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
470 ('% ', 'cumulative', 'self', ''), file=fp)
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
471 print('%5.5s %9.9s %8.8s %-8.8s' %
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
472 ("time", "seconds", "seconds", "name"), file=fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
473
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
474 for stat in stats:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
475 site = stat.site
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
476 sitelabel = '%s:%d:%s' % (site.filename(), site.lineno, site.function)
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
477 print('%6.2f %9.2f %9.2f %s' % (stat.selfpercent(),
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
478 stat.totalseconds(),
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
479 stat.selfseconds(),
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
480 sitelabel),
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
481 file=fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
482
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
483 def display_by_method(data, fp):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
484 '''Print the profiler data with each sample function represented
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
485 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
486 output as nested rows. Sorted by self-time per line.'''
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
487 print('%5.5s %10.10s %7.7s %-8.8s' %
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
488 ('% ', 'cumulative', 'self', ''), file=fp)
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
489 print('%5.5s %9.9s %8.8s %-8.8s' %
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
490 ("time", "seconds", "seconds", "name"), file=fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
491
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
492 stats = SiteStats.buildstats(data.samples)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
493
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
494 grouped = defaultdict(list)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
495 for stat in stats:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
496 grouped[stat.site.filename() + ":" + stat.site.function].append(stat)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
497
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
498 # compute sums for each function
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
499 functiondata = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
500 for fname, sitestats in grouped.iteritems():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
501 total_cum_sec = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
502 total_self_sec = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
503 total_percent = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
504 for stat in sitestats:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
505 total_cum_sec += stat.totalseconds()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
506 total_self_sec += stat.selfseconds()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
507 total_percent += stat.selfpercent()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
508
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
509 functiondata.append((fname,
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
510 total_cum_sec,
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
511 total_self_sec,
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
512 total_percent,
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
513 sitestats))
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
514
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
515 # sort by total self sec
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
516 functiondata.sort(reverse=True, key=lambda x: x[2])
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
517
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
518 for function in functiondata:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
519 if function[3] < 0.05:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
520 continue
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
521 print('%6.2f %9.2f %9.2f %s' % (function[3], # total percent
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
522 function[1], # total cum sec
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
523 function[2], # total self sec
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
524 function[0]), # file:function
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
525 file=fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
526 function[4].sort(reverse=True, key=lambda i: i.selfseconds())
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
527 for stat in function[4]:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
528 # only show line numbers for significant locations (>1% time spent)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
529 if stat.selfpercent() > 1:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
530 source = stat.site.getsource(25)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
531 stattuple = (stat.selfpercent(), stat.selfseconds(),
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
532 stat.site.lineno, source)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
533
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
534 print('%33.0f%% %6.2f line %s: %s' % (stattuple), file=fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
535
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
536 def display_about_method(data, fp, function=None, **kwargs):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
537 if function is None:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
538 raise Exception("Invalid function")
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
539
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
540 filename = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
541 if ':' in function:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
542 filename, function = function.split(':')
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
543
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
544 relevant_samples = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
545 parents = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
546 children = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
547
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
548 for sample in data.samples:
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
549 for i, site in enumerate(sample.stack):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
550 if site.function == function and (not filename
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
551 or site.filename() == filename):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
552 relevant_samples += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
553 if i != len(sample.stack) - 1:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
554 parent = sample.stack[i + 1]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
555 if parent in parents:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
556 parents[parent] = parents[parent] + 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
557 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
558 parents[parent] = 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
559
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
560 if site in children:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
561 children[site] = children[site] + 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
562 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
563 children[site] = 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
564
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
565 parents = [(parent, count) for parent, count in parents.iteritems()]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
566 parents.sort(reverse=True, key=lambda x: x[1])
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
567 for parent, count in parents:
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
568 print('%6.2f%% %s:%s line %s: %s' %
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
569 (count / relevant_samples * 100, parent.filename(),
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
570 parent.function, parent.lineno, parent.getsource(50)), file=fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
571
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
572 stats = SiteStats.buildstats(data.samples)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
573 stats = [s for s in stats
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
574 if s.site.function == function and
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
575 (not filename or s.site.filename() == filename)]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
576
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
577 total_cum_sec = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
578 total_self_sec = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
579 total_self_percent = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
580 total_cum_percent = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
581 for stat in stats:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
582 total_cum_sec += stat.totalseconds()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
583 total_self_sec += stat.selfseconds()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
584 total_self_percent += stat.selfpercent()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
585 total_cum_percent += stat.totalpercent()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
586
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
587 print(
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
588 '\n %s:%s Total: %0.2fs (%0.2f%%) Self: %0.2fs (%0.2f%%)\n' %
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
589 (
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
590 filename or '___',
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
591 function,
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
592 total_cum_sec,
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
593 total_cum_percent,
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
594 total_self_sec,
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
595 total_self_percent
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
596 ), file=fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
597
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
598 children = [(child, count) for child, count in children.iteritems()]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
599 children.sort(reverse=True, key=lambda x: x[1])
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
600 for child, count in children:
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
601 print(' %6.2f%% line %s: %s' %
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
602 (count / relevant_samples * 100, child.lineno,
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
603 child.getsource(50)), file=fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
604
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
605 def display_hotpath(data, fp, limit=0.05, **kwargs):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
606 class HotNode(object):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
607 def __init__(self, site):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
608 self.site = site
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
609 self.count = 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
610 self.children = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
611
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
612 def add(self, stack, time):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
613 self.count += time
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
614 site = stack[0]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
615 child = self.children.get(site)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
616 if not child:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
617 child = HotNode(site)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
618 self.children[site] = child
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
619
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
620 if len(stack) > 1:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
621 i = 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
622 # Skip boiler plate parts of the stack
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
623 while i < len(stack) and '%s:%s' % (stack[i].filename(), stack[i].function) in skips:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
624 i += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
625 if i < len(stack):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
626 child.add(stack[i:], time)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
627
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
628 root = HotNode(None)
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
629 lasttime = data.samples[0].time
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
630 for sample in data.samples:
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
631 root.add(sample.stack[::-1], sample.time - lasttime)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
632 lasttime = sample.time
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
633
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
634 def _write(node, depth, multiple_siblings):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
635 site = node.site
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
636 visiblechildren = [c for c in node.children.itervalues()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
637 if c.count >= (limit * root.count)]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
638 if site:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
639 indent = depth * 2 - 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
640 filename = ''
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
641 function = ''
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
642 if len(node.children) > 0:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
643 childsite = list(node.children.itervalues())[0].site
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
644 filename = (childsite.filename() + ':').ljust(15)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
645 function = childsite.function
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
646
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
647 # lots of string formatting
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
648 listpattern = ''.ljust(indent) +\
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
649 ('\\' if multiple_siblings else '|') +\
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
650 ' %4.1f%% %s %s'
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
651 liststring = listpattern % (node.count / root.count * 100,
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
652 filename, function)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
653 codepattern = '%' + str(55 - len(liststring)) + 's %s: %s'
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
654 codestring = codepattern % ('line', site.lineno, site.getsource(30))
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 finalstring = liststring + codestring
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
657 childrensamples = sum([c.count for c in node.children.itervalues()])
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
658 # 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
659 if node.count - childrensamples > (0.1 * root.count):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
660 finalstring = '\033[91m' + finalstring + '\033[0m'
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
661 # Make frames that didn't actually perform work dark grey
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
662 elif node.count - childrensamples == 0:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
663 finalstring = '\033[90m' + finalstring + '\033[0m'
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
664 print(finalstring, file=fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
665
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
666 newdepth = depth
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
667 if len(visiblechildren) > 1 or multiple_siblings:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
668 newdepth += 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
669
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
670 visiblechildren.sort(reverse=True, key=lambda x: x.count)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
671 for child in visiblechildren:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
672 _write(child, newdepth, len(visiblechildren) > 1)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
673
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
674 if root.count > 0:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
675 _write(root, 0, False)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
676
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
677 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
678 if scriptpath is None:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
679 scriptpath = os.environ['HOME'] + '/flamegraph.pl'
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
680 if not os.path.exists(scriptpath):
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
681 print("error: missing %s" % scriptpath, file=fp)
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
682 print("get it here: https://github.com/brendangregg/FlameGraph",
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
683 file=fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
684 return
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
685
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
686 fd, path = tempfile.mkstemp()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
687
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
688 file = open(path, "w+")
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
689
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
690 lines = {}
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
691 for sample in data.samples:
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
692 sites = [s.function for s in sample.stack]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
693 sites.reverse()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
694 line = ';'.join(sites)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
695 if line in lines:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
696 lines[line] = lines[line] + 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
697 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
698 lines[line] = 1
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
699
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
700 for line, count in lines.iteritems():
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
701 file.write("%s %s\n" % (line, count))
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 file.close()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
704
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
705 if outputfile is None:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
706 outputfile = '~/flamegraph.svg'
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
707
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
708 os.system("perl ~/flamegraph.pl %s > %s" % (path, outputfile))
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
709 print("Written to %s" % outputfile, file=fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
710
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
711 def write_to_json(data, fp):
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
712 samples = []
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
713
30258
eea89068a98d statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30257
diff changeset
714 for sample in data.samples:
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
715 stack = []
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 for frame in sample.stack:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
718 stack.append((frame.path, frame.lineno, frame.function))
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
719
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
720 samples.append((sample.time, stack))
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
721
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
722 print(json.dumps(samples), file=fp)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
723
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
724 def printusage():
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
725 print("""
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
726 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
727 the following forms:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
728
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
729 usage:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
730 hotpath [-l --limit percent]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
731 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
732 Red calls take over 10%% of the total time themselves.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
733 lines
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
734 Shows the actual sampled lines.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
735 functions
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
736 Shows the samples grouped by function.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
737 function [filename:]functionname
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
738 Shows the callers and callees of a particular function.
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
739 flame [-s --script-path] [-o --output-file path]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
740 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
741 Requires that ~/flamegraph.pl exist.
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
742 (Specify alternate script path with --script-path.)""")
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
743
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
744 def main(argv=None):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
745 if argv is None:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
746 argv = sys.argv
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 len(argv) == 1:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
749 printusage()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
750 return 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
751
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
752 displayargs = {}
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
753
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
754 optstart = 2
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
755 displayargs['function'] = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
756 if argv[1] == 'hotpath':
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
757 displayargs['format'] = DisplayFormats.Hotpath
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
758 elif argv[1] == 'lines':
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
759 displayargs['format'] = DisplayFormats.ByLine
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
760 elif argv[1] == 'functions':
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
761 displayargs['format'] = DisplayFormats.ByMethod
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
762 elif argv[1] == 'function':
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
763 displayargs['format'] = DisplayFormats.AboutMethod
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
764 displayargs['function'] = argv[2]
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
765 optstart = 3
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
766 elif argv[1] == 'flame':
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
767 displayargs['format'] = DisplayFormats.FlameGraph
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
768 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
769 printusage()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
770 return 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
771
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
772 # process options
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
773 try:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
774 opts, args = getopt.getopt(sys.argv[optstart:], "hl:f:o:p:",
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
775 ["help", "limit=", "file=", "output-file=", "script-path="])
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
776 except getopt.error as msg:
30257
7428223ed7c2 statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30256
diff changeset
777 print(msg)
30253
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
778 printusage()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
779 return 2
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
780
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
781 displayargs['limit'] = 0.05
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
782 path = None
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
783 for o, value in opts:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
784 if o in ("-l", "--limit"):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
785 displayargs['limit'] = float(value)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
786 elif o in ("-f", "--file"):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
787 path = value
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
788 elif o in ("-o", "--output-file"):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
789 displayargs['outputfile'] = value
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
790 elif o in ("-p", "--script-path"):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
791 displayargs['scriptpath'] = value
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
792 elif o in ("-h", "help"):
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
793 printusage()
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
794 return 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
795 else:
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
796 assert False, "unhandled option %s" % o
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
797
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
798 load_data(path=path)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
799
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
800 display(**displayargs)
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
801
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
802 return 0
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
803
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
804 if __name__ == "__main__":
b032a7b676c6 statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
805 sys.exit(main())