Mercurial > hg
annotate mercurial/statprof.py @ 39583:ee1e74ee037c
formatter: fill missing resources by formatter, not by resource mapper
While working on demand loading of ctx/fctx objects, I found it's weird
to support lookup in both directions. For instance, fctx can be loaded
from (ctx, path) pair, but ctx may also be derived from fctx.changectx()
in the original mapping. If the original mapping has had fctx but no ctx,
and if the new mapping provides {path}, we can't be sure if fctx should be
updated by fctx'.changectx()[path] or not.
This patch simply drops the support for the resolution in fctx -> ctx -> repo
direction.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sat, 01 Sep 2018 13:21:45 +0900 |
parents | 8943c1352b6c |
children | 4b7eb862692e |
rev | line source |
---|---|
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
1 #!/usr/bin/env python |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
2 ## statprof.py |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
3 ## Copyright (C) 2012 Bryan O'Sullivan <bos@serpentine.com> |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
4 ## Copyright (C) 2011 Alex Fraser <alex at phatcore dot com> |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
5 ## Copyright (C) 2004,2005 Andy Wingo <wingo at pobox dot com> |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
6 ## Copyright (C) 2001 Rob Browning <rlb at defaultvalue dot org> |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
7 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
8 ## This library is free software; you can redistribute it and/or |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
9 ## modify it under the terms of the GNU Lesser General Public |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
10 ## License as published by the Free Software Foundation; either |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
11 ## version 2.1 of the License, or (at your option) any later version. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
12 ## |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
13 ## This library is distributed in the hope that it will be useful, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
14 ## but WITHOUT ANY WARRANTY; without even the implied warranty of |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
15 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
16 ## Lesser General Public License for more details. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
17 ## |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
18 ## You should have received a copy of the GNU Lesser General Public |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
19 ## License along with this program; if not, contact: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
20 ## |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
21 ## Free Software Foundation Voice: +1-617-542-5942 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
22 ## 59 Temple Place - Suite 330 Fax: +1-617-542-2652 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
23 ## Boston, MA 02111-1307, USA gnu@gnu.org |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
24 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
25 """ |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
26 statprof is intended to be a fairly simple statistical profiler for |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
27 python. It was ported directly from a statistical profiler for guile, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
28 also named statprof, available from guile-lib [0]. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
29 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
30 [0] http://wingolog.org/software/guile-lib/statprof/ |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
31 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
32 To start profiling, call statprof.start(): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
33 >>> start() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
34 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
35 Then run whatever it is that you want to profile, for example: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
36 >>> import test.pystone; test.pystone.pystones() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
37 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
38 Then stop the profiling and print out the results: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
39 >>> stop() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
40 >>> display() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
41 % cumulative self |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
42 time seconds seconds name |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
43 26.72 1.40 0.37 pystone.py:79:Proc0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
44 13.79 0.56 0.19 pystone.py:133:Proc1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
45 13.79 0.19 0.19 pystone.py:208:Proc8 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
46 10.34 0.16 0.14 pystone.py:229:Func2 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
47 6.90 0.10 0.10 pystone.py:45:__init__ |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
48 4.31 0.16 0.06 pystone.py:53:copy |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
49 ... |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
50 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
51 All of the numerical data is statistically approximate. In the |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
52 following column descriptions, and in all of statprof, "time" refers |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
53 to execution time (both user and system), not wall clock time. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
54 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
55 % time |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
56 The percent of the time spent inside the procedure itself (not |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
57 counting children). |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
58 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
59 cumulative seconds |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
60 The total number of seconds spent in the procedure, including |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
61 children. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
62 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
63 self seconds |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
64 The total number of seconds spent in the procedure itself (not |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
65 counting children). |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
66 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
67 name |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
68 The name of the procedure. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
69 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
70 By default statprof keeps the data collected from previous runs. If you |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
71 want to clear the collected data, call reset(): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
72 >>> reset() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
73 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
74 reset() can also be used to change the sampling frequency from the |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
75 default of 1000 Hz. For example, to tell statprof to sample 50 times a |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
76 second: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
77 >>> reset(50) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
78 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
79 This means that statprof will sample the call stack after every 1/50 of |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
80 a second of user + system time spent running on behalf of the python |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
81 process. When your process is idle (for example, blocking in a read(), |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
82 as is the case at the listener), the clock does not advance. For this |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
83 reason statprof is not currently not suitable for profiling io-bound |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
84 operations. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
85 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
86 The profiler uses the hash of the code object itself to identify the |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
87 procedures, so it won't confuse different procedures with the same name. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
88 They will show up as two different rows in the output. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
89 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
90 Right now the profiler is quite simplistic. I cannot provide |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
91 call-graphs or other higher level information. What you see in the |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
92 table is pretty much all there is. Patches are welcome :-) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
93 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
94 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
95 Threading |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
96 --------- |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
97 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
98 Because signals only get delivered to the main thread in Python, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
99 statprof only profiles the main thread. However because the time |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
100 reporting function uses per-process timers, the results can be |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
101 significantly off if other threads' work patterns are not similar to the |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
102 main thread's work patterns. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
103 """ |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
104 # no-check-code |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
105 from __future__ import absolute_import, division, print_function |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
106 |
30256
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
107 import collections |
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
108 import contextlib |
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
109 import getopt |
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
110 import inspect |
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
111 import json |
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
112 import os |
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
113 import signal |
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
114 import sys |
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
115 import threading |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
116 import time |
30256
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
117 |
30578
c6ce11f2ee50
py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30568
diff
changeset
|
118 from . import ( |
30637
344e68882cd3
py3: replace os.environ with encoding.environ (part 4 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30578
diff
changeset
|
119 encoding, |
30578
c6ce11f2ee50
py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30568
diff
changeset
|
120 pycompat, |
c6ce11f2ee50
py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30568
diff
changeset
|
121 ) |
c6ce11f2ee50
py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30568
diff
changeset
|
122 |
30256
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
123 defaultdict = collections.defaultdict |
2ed0b3f9f79e
statprof: use absolute_imports
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30255
diff
changeset
|
124 contextmanager = contextlib.contextmanager |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
125 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
126 __all__ = ['start', 'stop', 'reset', 'display', 'profile'] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
127 |
32291
bd872f64a8ba
cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents:
31074
diff
changeset
|
128 skips = {"util.py:check", "extensions.py:closure", |
bd872f64a8ba
cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents:
31074
diff
changeset
|
129 "color.py:colorcmd", "dispatch.py:checkargs", |
bd872f64a8ba
cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents:
31074
diff
changeset
|
130 "dispatch.py:<lambda>", "dispatch.py:_runcatch", |
bd872f64a8ba
cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents:
31074
diff
changeset
|
131 "dispatch.py:_dispatch", "dispatch.py:_runcommand", |
bd872f64a8ba
cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents:
31074
diff
changeset
|
132 "pager.py:pagecmd", "dispatch.py:run", |
bd872f64a8ba
cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents:
31074
diff
changeset
|
133 "dispatch.py:dispatch", "dispatch.py:runcommand", |
bd872f64a8ba
cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents:
31074
diff
changeset
|
134 "hg.py:<module>", "evolve.py:warnobserrors", |
bd872f64a8ba
cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents:
31074
diff
changeset
|
135 } |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
136 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
137 ########################################################################### |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
138 ## Utils |
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 def clock(): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
141 times = os.times() |
38259
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
142 return (times[0] + times[1], times[4]) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
143 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
144 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
145 ########################################################################### |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
146 ## Collection data structures |
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 class ProfileState(object): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
149 def __init__(self, frequency=None): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
150 self.reset(frequency) |
38260
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
151 self.track = 'cpu' |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
152 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
153 def reset(self, frequency=None): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
154 # total so far |
38259
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
155 self.accumulated_time = (0.0, 0.0) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
156 # start_time when timer is active |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
157 self.last_start_time = None |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
158 # a float |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
159 if frequency: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
160 self.sample_interval = 1.0 / frequency |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
161 elif not hasattr(self, 'sample_interval'): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
162 # default to 1000 Hz |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
163 self.sample_interval = 1.0 / 1000.0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
164 else: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
165 # leave the frequency as it was |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
166 pass |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
167 self.remaining_prof_time = None |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
168 # for user start/stop nesting |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
169 self.profile_level = 0 |
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 self.samples = [] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
172 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
173 def accumulate_time(self, stop_time): |
38259
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
174 increment = ( |
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
175 stop_time[0] - self.last_start_time[0], |
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
176 stop_time[1] - self.last_start_time[1], |
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
177 ) |
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
178 self.accumulated_time = ( |
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
179 self.accumulated_time[0] + increment[0], |
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
180 self.accumulated_time[1] + increment[1], |
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
181 ) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
182 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
183 def seconds_per_sample(self): |
38260
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
184 return self.accumulated_time[self.timeidx] / len(self.samples) |
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
185 |
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
186 @property |
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
187 def timeidx(self): |
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
188 if self.track == 'real': |
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
189 return 1 |
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
190 return 0 |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
191 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
192 state = ProfileState() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
193 |
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 class CodeSite(object): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
196 cache = {} |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
197 |
30568
bb35fe8621f5
py3: use unicodes in __slots__
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30299
diff
changeset
|
198 __slots__ = (u'path', u'lineno', u'function', u'source') |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
199 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
200 def __init__(self, path, lineno, function): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
201 self.path = path |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
202 self.lineno = lineno |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
203 self.function = function |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
204 self.source = None |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
205 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
206 def __eq__(self, other): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
207 try: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
208 return (self.lineno == other.lineno and |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
209 self.path == other.path) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
210 except: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
211 return False |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
212 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
213 def __hash__(self): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
214 return hash((self.lineno, self.path)) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
215 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
216 @classmethod |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
217 def get(cls, path, lineno, function): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
218 k = (path, lineno) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
219 try: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
220 return cls.cache[k] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
221 except KeyError: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
222 v = cls(path, lineno, function) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
223 cls.cache[k] = v |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
224 return v |
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 def getsource(self, length): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
227 if self.source is None: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
228 lineno = self.lineno - 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
229 fp = None |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
230 try: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
231 fp = open(self.path) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
232 for i, line in enumerate(fp): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
233 if i == lineno: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
234 self.source = line.strip() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
235 break |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
236 except: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
237 pass |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
238 finally: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
239 if fp: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
240 fp.close() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
241 if self.source is None: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
242 self.source = '' |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
243 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
244 source = self.source |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
245 if len(source) > length: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
246 source = source[:(length - 3)] + "..." |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
247 return source |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
248 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
249 def filename(self): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
250 return os.path.basename(self.path) |
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 class Sample(object): |
30568
bb35fe8621f5
py3: use unicodes in __slots__
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30299
diff
changeset
|
253 __slots__ = (u'stack', u'time') |
30253
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 __init__(self, stack, time): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
256 self.stack = stack |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
257 self.time = time |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
258 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
259 @classmethod |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
260 def from_frame(cls, frame, time): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
261 stack = [] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
262 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
263 while frame: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
264 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
|
265 frame.f_code.co_name)) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
266 frame = frame.f_back |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
267 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
268 return Sample(stack, time) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
269 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
270 ########################################################################### |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
271 ## SIGPROF handler |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
272 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
273 def profile_signal_handler(signum, frame): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
274 if state.profile_level > 0: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
275 now = clock() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
276 state.accumulate_time(now) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
277 |
38260
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
278 timestamp = state.accumulated_time[state.timeidx] |
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
279 state.samples.append(Sample.from_frame(frame, timestamp)) |
30253
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 signal.setitimer(signal.ITIMER_PROF, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
282 state.sample_interval, 0.0) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
283 state.last_start_time = now |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
284 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
285 stopthread = threading.Event() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
286 def samplerthread(tid): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
287 while not stopthread.is_set(): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
288 now = clock() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
289 state.accumulate_time(now) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
290 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
291 frame = sys._current_frames()[tid] |
38260
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
292 |
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
293 timestamp = state.accumulated_time[state.timeidx] |
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
294 state.samples.append(Sample.from_frame(frame, timestamp)) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
295 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
296 state.last_start_time = now |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
297 time.sleep(state.sample_interval) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
298 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
299 stopthread.clear() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
300 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
301 ########################################################################### |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
302 ## Profiling API |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
303 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
304 def is_active(): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
305 return state.profile_level > 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
306 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
307 lastmechanism = None |
38260
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
308 def start(mechanism='thread', track='cpu'): |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
309 '''Install the profiling signal handler, and start profiling.''' |
38260
15a1e37f80bd
profiling: introduce a "profiling.time-track" option
Boris Feld <boris.feld@octobus.net>
parents:
38259
diff
changeset
|
310 state.track = track # note: nesting different mode won't work |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
311 state.profile_level += 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
312 if state.profile_level == 1: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
313 state.last_start_time = clock() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
314 rpt = state.remaining_prof_time |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
315 state.remaining_prof_time = None |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
316 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
317 global lastmechanism |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
318 lastmechanism = mechanism |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
319 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
320 if mechanism == 'signal': |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
321 signal.signal(signal.SIGPROF, profile_signal_handler) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
322 signal.setitimer(signal.ITIMER_PROF, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
323 rpt or state.sample_interval, 0.0) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
324 elif mechanism == 'thread': |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
325 frame = inspect.currentframe() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
326 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
|
327 state.thread = threading.Thread(target=samplerthread, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
328 args=(tid,), name="samplerthread") |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
329 state.thread.start() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
330 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
331 def stop(): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
332 '''Stop profiling, and uninstall the profiling signal handler.''' |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
333 state.profile_level -= 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
334 if state.profile_level == 0: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
335 if lastmechanism == 'signal': |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
336 rpt = signal.setitimer(signal.ITIMER_PROF, 0.0, 0.0) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
337 signal.signal(signal.SIGPROF, signal.SIG_IGN) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
338 state.remaining_prof_time = rpt[0] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
339 elif lastmechanism == 'thread': |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
340 stopthread.set() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
341 state.thread.join() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
342 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
343 state.accumulate_time(clock()) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
344 state.last_start_time = None |
30637
344e68882cd3
py3: replace os.environ with encoding.environ (part 4 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30578
diff
changeset
|
345 statprofpath = encoding.environ.get('STATPROF_DEST') |
30255
f42cd5434cc2
statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30254
diff
changeset
|
346 if statprofpath: |
f42cd5434cc2
statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30254
diff
changeset
|
347 save_data(statprofpath) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
348 |
30299
1e5346313963
statprof: return state from stop()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30258
diff
changeset
|
349 return state |
1e5346313963
statprof: return state from stop()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30258
diff
changeset
|
350 |
30255
f42cd5434cc2
statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30254
diff
changeset
|
351 def save_data(path): |
f42cd5434cc2
statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30254
diff
changeset
|
352 with open(path, 'w+') as file: |
38274
99188a7c8717
statprof: fix save and load
Boris Feld <boris.feld@octobus.net>
parents:
38260
diff
changeset
|
353 file.write("%f %f\n" % state.accumulated_time) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
354 for sample in state.samples: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
355 time = str(sample.time) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
356 stack = sample.stack |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
357 sites = ['\1'.join([s.path, str(s.lineno), s.function]) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
358 for s in stack] |
39092
8943c1352b6c
statprof: cleanup string construction
Boris Feld <boris.feld@octobus.net>
parents:
38697
diff
changeset
|
359 file.write("%s\0%s\n" % (time, '\0'.join(sites))) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
360 |
30255
f42cd5434cc2
statprof: require paths to save or load profile data
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30254
diff
changeset
|
361 def load_data(path): |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
362 lines = open(path, 'r').read().splitlines() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
363 |
38274
99188a7c8717
statprof: fix save and load
Boris Feld <boris.feld@octobus.net>
parents:
38260
diff
changeset
|
364 state.accumulated_time = [float(value) for value in lines[0].split()] |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
365 state.samples = [] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
366 for line in lines[1:]: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
367 parts = line.split('\0') |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
368 time = float(parts[0]) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
369 rawsites = parts[1:] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
370 sites = [] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
371 for rawsite in rawsites: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
372 siteparts = rawsite.split('\1') |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
373 sites.append(CodeSite.get(siteparts[0], int(siteparts[1]), |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
374 siteparts[2])) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
375 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
376 state.samples.append(Sample(sites, time)) |
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 def reset(frequency=None): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
381 '''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
|
382 profiler is running. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
383 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
384 The optional frequency argument specifies the number of samples to |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
385 collect per second.''' |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
386 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
|
387 CodeSite.cache.clear() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
388 state.reset(frequency) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
389 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
390 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
391 @contextmanager |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
392 def profile(): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
393 start() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
394 try: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
395 yield |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
396 finally: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
397 stop() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
398 display() |
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 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
401 ########################################################################### |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
402 ## Reporting API |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
403 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
404 class SiteStats(object): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
405 def __init__(self, site): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
406 self.site = site |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
407 self.selfcount = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
408 self.totalcount = 0 |
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 def addself(self): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
411 self.selfcount += 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
412 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
413 def addtotal(self): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
414 self.totalcount += 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
415 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
416 def selfpercent(self): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
417 return self.selfcount / len(state.samples) * 100 |
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 def totalpercent(self): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
420 return self.totalcount / len(state.samples) * 100 |
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 def selfseconds(self): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
423 return self.selfcount * state.seconds_per_sample() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
424 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
425 def totalseconds(self): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
426 return self.totalcount * state.seconds_per_sample() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
427 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
428 @classmethod |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
429 def buildstats(cls, samples): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
430 stats = {} |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
431 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
432 for sample in samples: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
433 for i, site in enumerate(sample.stack): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
434 sitestat = stats.get(site) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
435 if not sitestat: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
436 sitestat = SiteStats(site) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
437 stats[site] = sitestat |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
438 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
439 sitestat.addtotal() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
440 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
441 if i == 0: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
442 sitestat.addself() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
443 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
444 return [s for s in stats.itervalues()] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
445 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
446 class DisplayFormats: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
447 ByLine = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
448 ByMethod = 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
449 AboutMethod = 2 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
450 Hotpath = 3 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
451 FlameGraph = 4 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
452 Json = 5 |
30929
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
453 Chrome = 6 |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
454 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
455 def display(fp=None, format=3, data=None, **kwargs): |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
456 '''Print statistics, either to stdout or the given file object.''' |
38697
3c569172848d
statprof: small if cleanup
Boris Feld <boris.feld@octobus.net>
parents:
38274
diff
changeset
|
457 if data is None: |
3c569172848d
statprof: small if cleanup
Boris Feld <boris.feld@octobus.net>
parents:
38274
diff
changeset
|
458 data = state |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
459 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
460 if fp is None: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
461 import sys |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
462 fp = sys.stdout |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
463 if len(data.samples) == 0: |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
464 print('No samples recorded.', file=fp) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
465 return |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
466 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
467 if format == DisplayFormats.ByLine: |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
468 display_by_line(data, fp) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
469 elif format == DisplayFormats.ByMethod: |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
470 display_by_method(data, fp) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
471 elif format == DisplayFormats.AboutMethod: |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
472 display_about_method(data, fp, **kwargs) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
473 elif format == DisplayFormats.Hotpath: |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
474 display_hotpath(data, fp, **kwargs) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
475 elif format == DisplayFormats.FlameGraph: |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
476 write_to_flame(data, fp, **kwargs) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
477 elif format == DisplayFormats.Json: |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
478 write_to_json(data, fp) |
30929
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
479 elif format == DisplayFormats.Chrome: |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
480 write_to_chrome(data, fp, **kwargs) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
481 else: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
482 raise Exception("Invalid display format") |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
483 |
30929
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
484 if format not in (DisplayFormats.Json, DisplayFormats.Chrome): |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
485 print('---', file=fp) |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
486 print('Sample count: %d' % len(data.samples), file=fp) |
38259
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
487 print('Total time: %f seconds (%f wall)' % data.accumulated_time, |
af402c6b90db
statprof: also gather wall time
Boris Feld <boris.feld@octobus.net>
parents:
38164
diff
changeset
|
488 file=fp) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
489 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
490 def display_by_line(data, fp): |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
491 '''Print the profiler data with each sample line represented |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
492 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
|
493 stats = SiteStats.buildstats(data.samples) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
494 stats.sort(reverse=True, key=lambda x: x.selfseconds()) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
495 |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
496 print('%5.5s %10.10s %7.7s %-8.8s' % |
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
497 ('% ', 'cumulative', 'self', ''), file=fp) |
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
498 print('%5.5s %9.9s %8.8s %-8.8s' % |
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
499 ("time", "seconds", "seconds", "name"), file=fp) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
500 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
501 for stat in stats: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
502 site = stat.site |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
503 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
|
504 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
|
505 stat.totalseconds(), |
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
506 stat.selfseconds(), |
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
507 sitelabel), |
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
508 file=fp) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
509 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
510 def display_by_method(data, fp): |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
511 '''Print the profiler data with each sample function represented |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
512 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
|
513 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
|
514 print('%5.5s %10.10s %7.7s %-8.8s' % |
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
515 ('% ', 'cumulative', 'self', ''), file=fp) |
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
516 print('%5.5s %9.9s %8.8s %-8.8s' % |
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
517 ("time", "seconds", "seconds", "name"), file=fp) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
518 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
519 stats = SiteStats.buildstats(data.samples) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
520 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
521 grouped = defaultdict(list) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
522 for stat in stats: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
523 grouped[stat.site.filename() + ":" + stat.site.function].append(stat) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
524 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
525 # compute sums for each function |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
526 functiondata = [] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
527 for fname, sitestats in grouped.iteritems(): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
528 total_cum_sec = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
529 total_self_sec = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
530 total_percent = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
531 for stat in sitestats: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
532 total_cum_sec += stat.totalseconds() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
533 total_self_sec += stat.selfseconds() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
534 total_percent += stat.selfpercent() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
535 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
536 functiondata.append((fname, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
537 total_cum_sec, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
538 total_self_sec, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
539 total_percent, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
540 sitestats)) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
541 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
542 # sort by total self sec |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
543 functiondata.sort(reverse=True, key=lambda x: x[2]) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
544 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
545 for function in functiondata: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
546 if function[3] < 0.05: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
547 continue |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
548 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
|
549 function[1], # total cum sec |
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
550 function[2], # total self sec |
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
551 function[0]), # file:function |
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
552 file=fp) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
553 function[4].sort(reverse=True, key=lambda i: i.selfseconds()) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
554 for stat in function[4]: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
555 # only show line numbers for significant locations (>1% time spent) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
556 if stat.selfpercent() > 1: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
557 source = stat.site.getsource(25) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
558 stattuple = (stat.selfpercent(), stat.selfseconds(), |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
559 stat.site.lineno, source) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
560 |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
561 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
|
562 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
563 def display_about_method(data, fp, function=None, **kwargs): |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
564 if function is None: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
565 raise Exception("Invalid function") |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
566 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
567 filename = None |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
568 if ':' in function: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
569 filename, function = function.split(':') |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
570 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
571 relevant_samples = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
572 parents = {} |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
573 children = {} |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
574 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
575 for sample in data.samples: |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
576 for i, site in enumerate(sample.stack): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
577 if site.function == function and (not filename |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
578 or site.filename() == filename): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
579 relevant_samples += 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
580 if i != len(sample.stack) - 1: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
581 parent = sample.stack[i + 1] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
582 if parent in parents: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
583 parents[parent] = parents[parent] + 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
584 else: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
585 parents[parent] = 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
586 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
587 if site in children: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
588 children[site] = children[site] + 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
589 else: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
590 children[site] = 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
591 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
592 parents = [(parent, count) for parent, count in parents.iteritems()] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
593 parents.sort(reverse=True, key=lambda x: x[1]) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
594 for parent, count in parents: |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
595 print('%6.2f%% %s:%s line %s: %s' % |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
596 (count / relevant_samples * 100, parent.filename(), |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
597 parent.function, parent.lineno, parent.getsource(50)), file=fp) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
598 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
599 stats = SiteStats.buildstats(data.samples) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
600 stats = [s for s in stats |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
601 if s.site.function == function and |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
602 (not filename or s.site.filename() == filename)] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
603 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
604 total_cum_sec = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
605 total_self_sec = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
606 total_self_percent = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
607 total_cum_percent = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
608 for stat in stats: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
609 total_cum_sec += stat.totalseconds() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
610 total_self_sec += stat.selfseconds() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
611 total_self_percent += stat.selfpercent() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
612 total_cum_percent += stat.totalpercent() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
613 |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
614 print( |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
615 '\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
|
616 ( |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
617 filename or '___', |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
618 function, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
619 total_cum_sec, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
620 total_cum_percent, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
621 total_self_sec, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
622 total_self_percent |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
623 ), file=fp) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
624 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
625 children = [(child, count) for child, count in children.iteritems()] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
626 children.sort(reverse=True, key=lambda x: x[1]) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
627 for child, count in children: |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
628 print(' %6.2f%% line %s: %s' % |
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
629 (count / relevant_samples * 100, child.lineno, |
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
630 child.getsource(50)), file=fp) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
631 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
632 def display_hotpath(data, fp, limit=0.05, **kwargs): |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
633 class HotNode(object): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
634 def __init__(self, site): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
635 self.site = site |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
636 self.count = 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
637 self.children = {} |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
638 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
639 def add(self, stack, time): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
640 self.count += time |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
641 site = stack[0] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
642 child = self.children.get(site) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
643 if not child: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
644 child = HotNode(site) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
645 self.children[site] = child |
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 if len(stack) > 1: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
648 i = 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
649 # Skip boiler plate parts of the stack |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
650 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
|
651 i += 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
652 if i < len(stack): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
653 child.add(stack[i:], time) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
654 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
655 root = HotNode(None) |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
656 lasttime = data.samples[0].time |
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
657 for sample in data.samples: |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
658 root.add(sample.stack[::-1], sample.time - lasttime) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
659 lasttime = sample.time |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
660 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
661 def _write(node, depth, multiple_siblings): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
662 site = node.site |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
663 visiblechildren = [c for c in node.children.itervalues() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
664 if c.count >= (limit * root.count)] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
665 if site: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
666 indent = depth * 2 - 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
667 filename = '' |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
668 function = '' |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
669 if len(node.children) > 0: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
670 childsite = list(node.children.itervalues())[0].site |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
671 filename = (childsite.filename() + ':').ljust(15) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
672 function = childsite.function |
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 # lots of string formatting |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
675 listpattern = ''.ljust(indent) +\ |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
676 ('\\' if multiple_siblings else '|') +\ |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
677 ' %4.1f%% %s %s' |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
678 liststring = listpattern % (node.count / root.count * 100, |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
679 filename, function) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
680 codepattern = '%' + str(55 - len(liststring)) + 's %s: %s' |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
681 codestring = codepattern % ('line', site.lineno, site.getsource(30)) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
682 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
683 finalstring = liststring + codestring |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
684 childrensamples = sum([c.count for c in node.children.itervalues()]) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
685 # 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
|
686 if node.count - childrensamples > (0.1 * root.count): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
687 finalstring = '\033[91m' + finalstring + '\033[0m' |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
688 # Make frames that didn't actually perform work dark grey |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
689 elif node.count - childrensamples == 0: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
690 finalstring = '\033[90m' + finalstring + '\033[0m' |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
691 print(finalstring, file=fp) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
692 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
693 newdepth = depth |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
694 if len(visiblechildren) > 1 or multiple_siblings: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
695 newdepth += 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
696 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
697 visiblechildren.sort(reverse=True, key=lambda x: x.count) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
698 for child in visiblechildren: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
699 _write(child, newdepth, len(visiblechildren) > 1) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
700 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
701 if root.count > 0: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
702 _write(root, 0, False) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
703 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
704 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
|
705 if scriptpath is None: |
30637
344e68882cd3
py3: replace os.environ with encoding.environ (part 4 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30578
diff
changeset
|
706 scriptpath = encoding.environ['HOME'] + '/flamegraph.pl' |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
707 if not os.path.exists(scriptpath): |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
708 print("error: missing %s" % scriptpath, file=fp) |
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
709 print("get it here: https://github.com/brendangregg/FlameGraph", |
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
710 file=fp) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
711 return |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
712 |
38164
aac4be30e250
py3: wrap tempfile.mkstemp() to use bytes path
Yuya Nishihara <yuya@tcha.org>
parents:
35413
diff
changeset
|
713 fd, path = pycompat.mkstemp() |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
714 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
715 file = open(path, "w+") |
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 lines = {} |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
718 for sample in data.samples: |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
719 sites = [s.function for s in sample.stack] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
720 sites.reverse() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
721 line = ';'.join(sites) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
722 if line in lines: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
723 lines[line] = lines[line] + 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
724 else: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
725 lines[line] = 1 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
726 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
727 for line, count in lines.iteritems(): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
728 file.write("%s %s\n" % (line, count)) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
729 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
730 file.close() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
731 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
732 if outputfile is None: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
733 outputfile = '~/flamegraph.svg' |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
734 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
735 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
|
736 print("Written to %s" % outputfile, file=fp) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
737 |
30928
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
738 _pathcache = {} |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
739 def simplifypath(path): |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
740 '''Attempt to make the path to a Python module easier to read by |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
741 removing whatever part of the Python search path it was found |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
742 on.''' |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
743 |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
744 if path in _pathcache: |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
745 return _pathcache[path] |
31074
2912b06905dc
py3: use pycompat.fsencode() to convert __file__ to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30929
diff
changeset
|
746 hgpath = pycompat.fsencode(encoding.__file__).rsplit(os.sep, 2)[0] |
30928
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
747 for p in [hgpath] + sys.path: |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
748 prefix = p + os.sep |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
749 if path.startswith(prefix): |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
750 path = path[len(prefix):] |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
751 break |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
752 _pathcache[path] = path |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
753 return path |
be3a4fde38eb
statprof: add a path simplification function
Bryan O'Sullivan <bryano@fb.com>
parents:
30845
diff
changeset
|
754 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
755 def write_to_json(data, fp): |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
756 samples = [] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
757 |
30258
eea89068a98d
statprof: pass data structure to display functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30257
diff
changeset
|
758 for sample in data.samples: |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
759 stack = [] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
760 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
761 for frame in sample.stack: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
762 stack.append((frame.path, frame.lineno, frame.function)) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
763 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
764 samples.append((sample.time, stack)) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
765 |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
766 print(json.dumps(samples), file=fp) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
767 |
30929
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
768 def write_to_chrome(data, fp, minthreshold=0.005, maxthreshold=0.999): |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
769 samples = [] |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
770 laststack = collections.deque() |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
771 lastseen = collections.deque() |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
772 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
773 # The Chrome tracing format allows us to use a compact stack |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
774 # representation to save space. It's fiddly but worth it. |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
775 # We maintain a bijection between stack and ID. |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
776 stack2id = {} |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
777 id2stack = [] # will eventually be rendered |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
778 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
779 def stackid(stack): |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
780 if not stack: |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
781 return |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
782 if stack in stack2id: |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
783 return stack2id[stack] |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
784 parent = stackid(stack[1:]) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
785 myid = len(stack2id) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
786 stack2id[stack] = myid |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
787 id2stack.append(dict(category=stack[0][0], name='%s %s' % stack[0])) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
788 if parent is not None: |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
789 id2stack[-1].update(parent=parent) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
790 return myid |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
791 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
792 def endswith(a, b): |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
793 return list(a)[-len(b):] == list(b) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
794 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
795 # The sampling profiler can sample multiple times without |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
796 # advancing the clock, potentially causing the Chrome trace viewer |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
797 # to render single-pixel columns that we cannot zoom in on. We |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
798 # work around this by pretending that zero-duration samples are a |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
799 # millisecond in length. |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
800 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
801 clamp = 0.001 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
802 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
803 # We provide knobs that by default attempt to filter out stack |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
804 # frames that are too noisy: |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
805 # |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
806 # * A few take almost all execution time. These are usually boring |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
807 # setup functions, giving a stack that is deep but uninformative. |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
808 # |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
809 # * Numerous samples take almost no time, but introduce lots of |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
810 # noisy, oft-deep "spines" into a rendered profile. |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
811 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
812 blacklist = set() |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
813 totaltime = data.samples[-1].time - data.samples[0].time |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
814 minthreshold = totaltime * minthreshold |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
815 maxthreshold = max(totaltime * maxthreshold, clamp) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
816 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
817 def poplast(): |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
818 oldsid = stackid(tuple(laststack)) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
819 oldcat, oldfunc = laststack.popleft() |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
820 oldtime, oldidx = lastseen.popleft() |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
821 duration = sample.time - oldtime |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
822 if minthreshold <= duration <= maxthreshold: |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
823 # ensure no zero-duration events |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
824 sampletime = max(oldtime + clamp, sample.time) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
825 samples.append(dict(ph='E', name=oldfunc, cat=oldcat, sf=oldsid, |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
826 ts=sampletime*1e6, pid=0)) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
827 else: |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
828 blacklist.add(oldidx) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
829 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
830 # Much fiddling to synthesize correctly(ish) nested begin/end |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
831 # events given only stack snapshots. |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
832 |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
833 for sample in data.samples: |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
834 tos = sample.stack[0] |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
835 name = tos.function |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
836 path = simplifypath(tos.path) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
837 stack = tuple((('%s:%d' % (simplifypath(frame.path), frame.lineno), |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
838 frame.function) for frame in sample.stack)) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
839 qstack = collections.deque(stack) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
840 if laststack == qstack: |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
841 continue |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
842 while laststack and qstack and laststack[-1] == qstack[-1]: |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
843 laststack.pop() |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
844 qstack.pop() |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
845 while laststack: |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
846 poplast() |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
847 for f in reversed(qstack): |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
848 lastseen.appendleft((sample.time, len(samples))) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
849 laststack.appendleft(f) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
850 path, name = f |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
851 sid = stackid(tuple(laststack)) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
852 samples.append(dict(ph='B', name=name, cat=path, ts=sample.time*1e6, |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
853 sf=sid, pid=0)) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
854 laststack = collections.deque(stack) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
855 while laststack: |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
856 poplast() |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
857 events = [s[1] for s in enumerate(samples) if s[0] not in blacklist] |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
858 frames = collections.OrderedDict((str(k), v) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
859 for (k,v) in enumerate(id2stack)) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
860 json.dump(dict(traceEvents=events, stackFrames=frames), fp, indent=1) |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
861 fp.write('\n') |
cb440e7af05d
statprof: allow rendering in the Chrome trace viewer format
Bryan O'Sullivan <bryano@fb.com>
parents:
30928
diff
changeset
|
862 |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
863 def printusage(): |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
864 print(""" |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
865 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
|
866 the following forms: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
867 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
868 usage: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
869 hotpath [-l --limit percent] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
870 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
|
871 Red calls take over 10%% of the total time themselves. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
872 lines |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
873 Shows the actual sampled lines. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
874 functions |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
875 Shows the samples grouped by function. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
876 function [filename:]functionname |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
877 Shows the callers and callees of a particular function. |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
878 flame [-s --script-path] [-o --output-file path] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
879 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
|
880 Requires that ~/flamegraph.pl exist. |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
881 (Specify alternate script path with --script-path.)""") |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
882 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
883 def main(argv=None): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
884 if argv is None: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
885 argv = sys.argv |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
886 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
887 if len(argv) == 1: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
888 printusage() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
889 return 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
890 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
891 displayargs = {} |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
892 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
893 optstart = 2 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
894 displayargs['function'] = None |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
895 if argv[1] == 'hotpath': |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
896 displayargs['format'] = DisplayFormats.Hotpath |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
897 elif argv[1] == 'lines': |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
898 displayargs['format'] = DisplayFormats.ByLine |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
899 elif argv[1] == 'functions': |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
900 displayargs['format'] = DisplayFormats.ByMethod |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
901 elif argv[1] == 'function': |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
902 displayargs['format'] = DisplayFormats.AboutMethod |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
903 displayargs['function'] = argv[2] |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
904 optstart = 3 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
905 elif argv[1] == 'flame': |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
906 displayargs['format'] = DisplayFormats.FlameGraph |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
907 else: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
908 printusage() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
909 return 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
910 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
911 # process options |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
912 try: |
30578
c6ce11f2ee50
py3: make a bytes version of getopt.getopt()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30568
diff
changeset
|
913 opts, args = pycompat.getoptb(sys.argv[optstart:], "hl:f:o:p:", |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
914 ["help", "limit=", "file=", "output-file=", "script-path="]) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
915 except getopt.error as msg: |
30257
7428223ed7c2
statprof: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30256
diff
changeset
|
916 print(msg) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
917 printusage() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
918 return 2 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
919 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
920 displayargs['limit'] = 0.05 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
921 path = None |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
922 for o, value in opts: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
923 if o in ("-l", "--limit"): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
924 displayargs['limit'] = float(value) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
925 elif o in ("-f", "--file"): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
926 path = value |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
927 elif o in ("-o", "--output-file"): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
928 displayargs['outputfile'] = value |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
929 elif o in ("-p", "--script-path"): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
930 displayargs['scriptpath'] = value |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
931 elif o in ("-h", "help"): |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
932 printusage() |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
933 return 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
934 else: |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
935 assert False, "unhandled option %s" % o |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
936 |
30845
262c2be8ea5a
statprof: require input file
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30637
diff
changeset
|
937 if not path: |
262c2be8ea5a
statprof: require input file
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30637
diff
changeset
|
938 print('must specify --file to load') |
262c2be8ea5a
statprof: require input file
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30637
diff
changeset
|
939 return 1 |
262c2be8ea5a
statprof: require input file
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30637
diff
changeset
|
940 |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
941 load_data(path=path) |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
942 |
35370
c5853c9a6545
py3: handle keyword arguments correctly in statprof.py
Pulkit Goyal <7895pulkit@gmail.com>
parents:
32291
diff
changeset
|
943 display(**pycompat.strkwargs(displayargs)) |
30253
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
944 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
945 return 0 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
946 |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
947 if __name__ == "__main__": |
b032a7b676c6
statprof: vendor statprof.py
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
948 sys.exit(main()) |