ruby-prof 0.18.0-x64-mingw32 → 1.1.0-x64-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES +32 -0
- data/LICENSE +2 -2
- data/README.rdoc +1 -483
- data/Rakefile +3 -6
- data/bin/ruby-prof +65 -30
- data/ext/ruby_prof/extconf.rb +6 -38
- data/ext/ruby_prof/rp_allocation.c +279 -0
- data/ext/ruby_prof/rp_allocation.h +31 -0
- data/ext/ruby_prof/rp_call_info.c +129 -283
- data/ext/ruby_prof/rp_call_info.h +16 -34
- data/ext/ruby_prof/rp_measure_allocations.c +25 -49
- data/ext/ruby_prof/rp_measure_memory.c +21 -56
- data/ext/ruby_prof/rp_measure_process_time.c +35 -39
- data/ext/ruby_prof/rp_measure_wall_time.c +36 -19
- data/ext/ruby_prof/rp_measurement.c +230 -0
- data/ext/ruby_prof/rp_measurement.h +50 -0
- data/ext/ruby_prof/rp_method.c +389 -389
- data/ext/ruby_prof/rp_method.h +34 -39
- data/ext/ruby_prof/rp_profile.c +895 -0
- data/ext/ruby_prof/rp_profile.h +37 -0
- data/ext/ruby_prof/rp_stack.c +103 -80
- data/ext/ruby_prof/rp_stack.h +5 -12
- data/ext/ruby_prof/rp_thread.c +143 -83
- data/ext/ruby_prof/rp_thread.h +15 -6
- data/ext/ruby_prof/ruby_prof.c +11 -757
- data/ext/ruby_prof/ruby_prof.h +4 -47
- data/ext/ruby_prof/vc/ruby_prof.vcxproj +10 -8
- data/lib/{2.6.3 → 2.6.5}/ruby_prof.so +0 -0
- data/lib/ruby-prof.rb +2 -18
- data/lib/ruby-prof/assets/call_stack_printer.html.erb +713 -0
- data/lib/ruby-prof/assets/call_stack_printer.png +0 -0
- data/lib/ruby-prof/assets/graph_printer.html.erb +356 -0
- data/lib/ruby-prof/call_info.rb +35 -93
- data/lib/ruby-prof/call_info_visitor.rb +19 -21
- data/lib/ruby-prof/compatibility.rb +37 -107
- data/lib/ruby-prof/exclude_common_methods.rb +198 -0
- data/lib/ruby-prof/measurement.rb +14 -0
- data/lib/ruby-prof/method_info.rb +52 -83
- data/lib/ruby-prof/printers/abstract_printer.rb +73 -50
- data/lib/ruby-prof/printers/call_info_printer.rb +13 -3
- data/lib/ruby-prof/printers/call_stack_printer.rb +62 -145
- data/lib/ruby-prof/printers/call_tree_printer.rb +20 -12
- data/lib/ruby-prof/printers/dot_printer.rb +5 -5
- data/lib/ruby-prof/printers/flat_printer.rb +6 -24
- data/lib/ruby-prof/printers/graph_html_printer.rb +6 -192
- data/lib/ruby-prof/printers/graph_printer.rb +13 -15
- data/lib/ruby-prof/printers/multi_printer.rb +66 -23
- data/lib/ruby-prof/profile.rb +10 -3
- data/lib/ruby-prof/rack.rb +0 -3
- data/lib/ruby-prof/thread.rb +12 -12
- data/lib/ruby-prof/version.rb +1 -1
- data/ruby-prof.gemspec +2 -2
- data/test/abstract_printer_test.rb +0 -27
- data/test/alias_test.rb +129 -0
- data/test/basic_test.rb +41 -40
- data/test/call_info_visitor_test.rb +3 -3
- data/test/dynamic_method_test.rb +0 -2
- data/test/fiber_test.rb +11 -17
- data/test/gc_test.rb +96 -0
- data/test/line_number_test.rb +120 -39
- data/test/marshal_test.rb +119 -0
- data/test/measure_allocations.rb +30 -0
- data/test/measure_allocations_test.rb +371 -12
- data/test/measure_allocations_trace_test.rb +385 -0
- data/test/measure_memory_trace_test.rb +756 -0
- data/test/measure_process_time_test.rb +821 -33
- data/test/measure_times.rb +54 -0
- data/test/measure_wall_time_test.rb +349 -145
- data/test/multi_printer_test.rb +1 -34
- data/test/parser_timings.rb +24 -0
- data/test/pause_resume_test.rb +5 -5
- data/test/prime.rb +2 -0
- data/test/printer_call_stack_test.rb +28 -0
- data/test/printer_call_tree_test.rb +31 -0
- data/test/printer_flat_test.rb +68 -0
- data/test/printer_graph_html_test.rb +60 -0
- data/test/printer_graph_test.rb +41 -0
- data/test/printers_test.rb +32 -166
- data/test/printing_recursive_graph_test.rb +26 -72
- data/test/recursive_test.rb +72 -77
- data/test/stack_printer_test.rb +2 -15
- data/test/start_stop_test.rb +22 -25
- data/test/test_helper.rb +5 -248
- data/test/thread_test.rb +11 -54
- data/test/unique_call_path_test.rb +16 -28
- data/test/yarv_test.rb +1 -0
- metadata +28 -36
- data/examples/flat.txt +0 -50
- data/examples/graph.dot +0 -84
- data/examples/graph.html +0 -823
- data/examples/graph.txt +0 -139
- data/examples/multi.flat.txt +0 -23
- data/examples/multi.graph.html +0 -760
- data/examples/multi.grind.dat +0 -114
- data/examples/multi.stack.html +0 -547
- data/examples/stack.html +0 -547
- data/ext/ruby_prof/rp_measure.c +0 -40
- data/ext/ruby_prof/rp_measure.h +0 -45
- data/ext/ruby_prof/rp_measure_cpu_time.c +0 -136
- data/ext/ruby_prof/rp_measure_gc_runs.c +0 -73
- data/ext/ruby_prof/rp_measure_gc_time.c +0 -60
- data/lib/ruby-prof/aggregate_call_info.rb +0 -76
- data/lib/ruby-prof/assets/call_stack_printer.css.html +0 -117
- data/lib/ruby-prof/assets/call_stack_printer.js.html +0 -385
- data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +0 -83
- data/lib/ruby-prof/profile/exclude_common_methods.rb +0 -207
- data/lib/ruby-prof/profile/legacy_method_elimination.rb +0 -50
- data/test/aggregate_test.rb +0 -136
- data/test/block_test.rb +0 -74
- data/test/call_info_test.rb +0 -78
- data/test/issue137_test.rb +0 -63
- data/test/measure_cpu_time_test.rb +0 -212
- data/test/measure_gc_runs_test.rb +0 -32
- data/test/measure_gc_time_test.rb +0 -36
- data/test/measure_memory_test.rb +0 -33
- data/test/method_elimination_test.rb +0 -84
- data/test/module_test.rb +0 -45
- data/test/stack_test.rb +0 -138
Binary file
|
@@ -0,0 +1,356 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<style media="all" type="text/css">
|
5
|
+
body {
|
6
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
7
|
+
background-color: #F5F7FB;
|
8
|
+
margin: 0;
|
9
|
+
padding: 0;
|
10
|
+
font-size: 16px;
|
11
|
+
}
|
12
|
+
|
13
|
+
table {
|
14
|
+
border-collapse: collapse;
|
15
|
+
/* border: 1px solid #E1E3E7; */
|
16
|
+
border: 1px solid #F3F9FE;
|
17
|
+
font-size: 14px;
|
18
|
+
line-height: normal;
|
19
|
+
width: 100%;
|
20
|
+
}
|
21
|
+
|
22
|
+
table:empty {
|
23
|
+
display: none;
|
24
|
+
}
|
25
|
+
|
26
|
+
th:first-child {
|
27
|
+
border-left: 0;
|
28
|
+
}
|
29
|
+
|
30
|
+
th {
|
31
|
+
text-align: center;
|
32
|
+
background: #F3F9FE;
|
33
|
+
padding: 1rem;
|
34
|
+
/* border-left: 1px solid #E1E3E7; */
|
35
|
+
text-transform: uppercase;
|
36
|
+
font-size: 13px;
|
37
|
+
letter-spacing: 1px;
|
38
|
+
}
|
39
|
+
|
40
|
+
tr.break td {
|
41
|
+
border: 0;
|
42
|
+
border-top: 1px solid #BDC3DD;
|
43
|
+
padding: 0;
|
44
|
+
margin: 0;
|
45
|
+
}
|
46
|
+
|
47
|
+
tr.method td {
|
48
|
+
font-weight: bold;
|
49
|
+
}
|
50
|
+
|
51
|
+
td {
|
52
|
+
padding: 0.5em;
|
53
|
+
}
|
54
|
+
|
55
|
+
td:first-child {
|
56
|
+
width: 190px;
|
57
|
+
}
|
58
|
+
|
59
|
+
tr > td > table {
|
60
|
+
box-shadow: 0px -2px 1px #F9FAFB, 0px 1px 1px #E4EEEE, 0px 1px 2px #EEF3F8;
|
61
|
+
border-radius: 2px;
|
62
|
+
overflow: hidden;
|
63
|
+
}
|
64
|
+
|
65
|
+
tr.break + tr > td.method_name {
|
66
|
+
font-weight: bold;
|
67
|
+
}
|
68
|
+
|
69
|
+
td {
|
70
|
+
/* I'm removing this border because I think it looks way cleaner without it but feel free to add it if you feel it's necessary */
|
71
|
+
/* border-left: 1px solid #E1E3E7; */
|
72
|
+
text-align: center;
|
73
|
+
}
|
74
|
+
|
75
|
+
a {
|
76
|
+
text-decoration: none;
|
77
|
+
}
|
78
|
+
|
79
|
+
.method_name {
|
80
|
+
text-align: left;
|
81
|
+
}
|
82
|
+
|
83
|
+
tfoot td {
|
84
|
+
text-align: left;
|
85
|
+
}
|
86
|
+
|
87
|
+
.report-header {
|
88
|
+
background-color: #0D2483;
|
89
|
+
color: white;
|
90
|
+
padding: 1.5rem 2rem;
|
91
|
+
}
|
92
|
+
|
93
|
+
.report-header > div {
|
94
|
+
display: flex;
|
95
|
+
flex-direction: row;
|
96
|
+
align-items: center;
|
97
|
+
}
|
98
|
+
|
99
|
+
.report-header h1 {
|
100
|
+
margin-bottom: 0;
|
101
|
+
}
|
102
|
+
|
103
|
+
h1, h2, h3, h4, h5, h6 {
|
104
|
+
margin-top: 0;
|
105
|
+
margin-bottom: 0.5rem;
|
106
|
+
}
|
107
|
+
|
108
|
+
h6 {
|
109
|
+
font-size: 0.75rem;
|
110
|
+
text-transform: uppercase;
|
111
|
+
letter-spacing: 1.5px;
|
112
|
+
color: rgba(255, 255, 255, 0.6);
|
113
|
+
}
|
114
|
+
|
115
|
+
.table-header {
|
116
|
+
padding: 3rem 0 1rem;
|
117
|
+
}
|
118
|
+
|
119
|
+
.table-wrapper {
|
120
|
+
margin: 1rem auto;
|
121
|
+
max-width: 1440px;
|
122
|
+
padding: 4rem 5rem;
|
123
|
+
background: white;
|
124
|
+
border-radius: 0.5rem;
|
125
|
+
}
|
126
|
+
|
127
|
+
.center {
|
128
|
+
max-width: 1440px;
|
129
|
+
margin: 0 auto;
|
130
|
+
}
|
131
|
+
|
132
|
+
.layout-right {
|
133
|
+
margin-left: auto;
|
134
|
+
}
|
135
|
+
|
136
|
+
.text-right {
|
137
|
+
display: flex;
|
138
|
+
align-items: flex-end;
|
139
|
+
flex-direction: column;
|
140
|
+
}
|
141
|
+
|
142
|
+
.timestamp {
|
143
|
+
font-size: 12px;
|
144
|
+
margin-bottom: 1rem;
|
145
|
+
color: rgba(255, 255, 255, 0.6);
|
146
|
+
}
|
147
|
+
|
148
|
+
.logo {
|
149
|
+
width: 140px;
|
150
|
+
height: 30px;
|
151
|
+
opacity: 0.5;
|
152
|
+
background-repeat: no-repeat;
|
153
|
+
background-image: url("data:image/svg+xml,%3Csvg id='Layer_1' data-name='Layer 1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 190 41'%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill:%23fff%7D%3C/style%3E%3C/defs%3E%3Cpath class='cls-1' d='M63.49 16.74c0-1.37-.91-2-2.26-2h-3.38v3.93h3.58c1.24.01 2.06-.56 2.06-1.93zM110.43 14.75h-3.6v5h3.6a2.32 2.32 0 0 0 2.5-2.49 2.34 2.34 0 0 0-2.5-2.51zM128.77 14.75h-3.53v4.94h3.53a2.28 2.28 0 0 0 2.47-2.45 2.3 2.3 0 0 0-2.47-2.49zM61.81 21.83h-4v4.32h3.91c1.44 0 2.45-.62 2.45-2.14s-.99-2.18-2.36-2.18zM21 14.75h-3.57v4.94H21a2.28 2.28 0 0 0 2.47-2.45A2.3 2.3 0 0 0 21 14.75z'/%3E%3Cpath class='cls-1' d='M184 .44H5.87A4.93 4.93 0 0 0 .94 5.37V35.5a4.94 4.94 0 0 0 4.93 4.94H184a4.94 4.94 0 0 0 4.94-4.94V5.37A4.94 4.94 0 0 0 184 .44zm-34.38 10.78c4.79 0 8.46 2.89 9.18 7.54h-3.86a5.48 5.48 0 0 0-10.68 0h-3.83c.71-4.65 4.36-7.54 9.19-7.54zM24 29.44L20.46 23h-3v6.46h-3.72v-18h7.68c3.41 0 5.78 2.07 5.78 5.76a5.34 5.34 0 0 1-2.88 5.14l3.82 7.06zm24.31-7.3c0 4.8-2.92 7.56-7.63 7.56S33 26.94 33 22.14V11.48h3.69v10.61c0 2.81 1.37 4.32 4 4.32s3.94-1.51 3.94-4.32V11.48h3.69zm13.92 7.3h-8v-18h7.52c3.24 0 5.59 1.61 5.59 5A4 4 0 0 1 65.51 20 4.22 4.22 0 0 1 68 24.21c0 3.43-2.4 5.23-5.81 5.23zm19.66-6.92v6.92h-3.7v-6.92l-6.81-11h4.29L80 18.85l4.34-7.37h4.32zm16-.5h-7.62v-3.26h7.59zm13 1h-4v6.39h-3.72v-18h7.77c3.41 0 5.79 2.09 5.79 5.79s-2.41 5.85-5.82 5.85zm20.86 6.39L128.26 23h-3v6.46h-3.72v-18h7.69c3.4 0 5.78 2.07 5.78 5.76a5.34 5.34 0 0 1-2.88 5.14l3.87 7.08zm17.85.26c-4.88 0-8.55-2.95-9.21-7.68h3.81A5.49 5.49 0 0 0 155 22h3.84c-.69 4.75-4.38 7.7-9.22 7.7zm18.4-.23h-3.72v-3.7H168zm6.36-7.54h-10.05v-3.26h10.08zm1.44-7.16h-11.49v-3.26h11.52z'/%3E%3C/svg%3E");
|
154
|
+
}
|
155
|
+
</style>
|
156
|
+
</head>
|
157
|
+
<body>
|
158
|
+
<div class="report-header">
|
159
|
+
<div class="center">
|
160
|
+
<div class="layout-left">
|
161
|
+
<h6>Profile Report</h6>
|
162
|
+
<h1><%= @result.measure_mode_string.capitalize %></h1>
|
163
|
+
</div>
|
164
|
+
<div class="layout-right text-right">
|
165
|
+
<div class="timestamp"><%= Time.now.strftime(self.time_format) %></div>
|
166
|
+
<div class="logo"></div>
|
167
|
+
</div>
|
168
|
+
</div>
|
169
|
+
</div>
|
170
|
+
<div class="table-wrapper">
|
171
|
+
<table>
|
172
|
+
<tr>
|
173
|
+
<th>Thread ID</th>
|
174
|
+
<th>Fiber ID</th>
|
175
|
+
<th>Total</th>
|
176
|
+
</tr>
|
177
|
+
<% for thread in @result.threads %>
|
178
|
+
<tr>
|
179
|
+
<td><%= thread.id %></td>
|
180
|
+
<td><a href="#<%= thread.fiber_id %>"><%= thread.fiber_id %></a></td>
|
181
|
+
<td><%= thread.total_time %></td>
|
182
|
+
</tr>
|
183
|
+
<% end %>
|
184
|
+
</table>
|
185
|
+
|
186
|
+
<!-- Methods Tables -->
|
187
|
+
<%
|
188
|
+
for thread in @result.threads
|
189
|
+
methods = thread.methods
|
190
|
+
total_time = thread.total_time
|
191
|
+
%>
|
192
|
+
<h2><a name="<%= thread.fiber_id %>">Thread <%= thread.id %>, Fiber: <%= thread.fiber_id %></a></h2>
|
193
|
+
<table>
|
194
|
+
<thead>
|
195
|
+
<tr>
|
196
|
+
<th>%Total</th>
|
197
|
+
<th>%Self</th>
|
198
|
+
<th>Total</th>
|
199
|
+
<th>Self</th>
|
200
|
+
<th>Wait</th>
|
201
|
+
<th>Child</th>
|
202
|
+
<th>Calls</th>
|
203
|
+
<th class="method_name">Name</th>
|
204
|
+
<% if @result.track_allocations? %>
|
205
|
+
<th>Allocations</th>
|
206
|
+
<% end %>
|
207
|
+
<th>Line</th>
|
208
|
+
</tr>
|
209
|
+
</thead>
|
210
|
+
<tbody>
|
211
|
+
<% min_time = @options[:min_time] || (@options[:nonzero] ? 0.005 : nil)
|
212
|
+
sorted_methods = sort_method ? methods.sort_by(&sort_method) : methods.sort
|
213
|
+
sorted_methods.reverse_each do |method|
|
214
|
+
total_percentage = (method.total_time/total_time) * 100
|
215
|
+
next if total_percentage < min_percent
|
216
|
+
next if min_time && method.total_time < min_time
|
217
|
+
self_percentage = (method.self_time/total_time) * 100 %>
|
218
|
+
|
219
|
+
<!-- Parents -->
|
220
|
+
<% for caller in method.callers.sort
|
221
|
+
next if method.root?
|
222
|
+
next if min_time && caller.total_time < min_time %>
|
223
|
+
<tr>
|
224
|
+
<td> </td>
|
225
|
+
<td> </td>
|
226
|
+
<td><%= sprintf("%.2f", caller.total_time) %></td>
|
227
|
+
<td><%= sprintf("%.2f", caller.self_time) %></td>
|
228
|
+
<td><%= sprintf("%.2f", caller.wait_time) %></td>
|
229
|
+
<td><%= sprintf("%.2f", caller.children_time) %></td>
|
230
|
+
<td><%= "#{caller.called}/#{method.called}" %></td>
|
231
|
+
<td class="method_name"><%= create_link(thread, total_time, caller.parent) %></td>
|
232
|
+
<% if @result.track_allocations? %>
|
233
|
+
<td>-</td>
|
234
|
+
<% end %>
|
235
|
+
<td><%= if caller.parent.source_file
|
236
|
+
file_link(caller.parent.source_file, caller.line)
|
237
|
+
end %></td>
|
238
|
+
</tr>
|
239
|
+
<% end %>
|
240
|
+
<tr class="method">
|
241
|
+
<td><%= sprintf("%.2f%%", total_percentage) %></td>
|
242
|
+
<td><%= sprintf("%.2f%%", self_percentage) %></td>
|
243
|
+
<td><%= sprintf("%.2f", method.total_time) %></td>
|
244
|
+
<td><%= sprintf("%.2f", method.self_time) %></td>
|
245
|
+
<td><%= sprintf("%.2f", method.wait_time) %></td>
|
246
|
+
<td><%= sprintf("%.2f", method.children_time) %></td>
|
247
|
+
<td><%= sprintf("%i", method.called) %></td>
|
248
|
+
<td class="method_name">
|
249
|
+
<a name="<%= method_href(thread, method) %>">
|
250
|
+
<%= method.recursive? ? "*" : " " %><%= h method.full_name %>
|
251
|
+
</a>
|
252
|
+
</td>
|
253
|
+
|
254
|
+
<% if @result.track_allocations? %>
|
255
|
+
<td>
|
256
|
+
<% count = method.allocations.reduce(0) do |size, allocation|
|
257
|
+
size += allocation.count
|
258
|
+
end %>
|
259
|
+
<% if count > 0 %>
|
260
|
+
<a class="allocations" href="#<%= method_href(thread, method) %>_allocations" %><%= count %></a>
|
261
|
+
<% else %>
|
262
|
+
0
|
263
|
+
<% end %>
|
264
|
+
</td>
|
265
|
+
<% end %>
|
266
|
+
|
267
|
+
<td><%= if method.source_file
|
268
|
+
file_link(method.source_file, method.line)
|
269
|
+
end %></td>
|
270
|
+
</tr>
|
271
|
+
|
272
|
+
<% if @result.track_allocations? %>
|
273
|
+
<tr>
|
274
|
+
<td colspan="10">
|
275
|
+
<table id="<%= method_href(thread, method) %>_allocations" class="allocations" style="display: none">
|
276
|
+
<% for allocation in method.allocations %>
|
277
|
+
<tr>
|
278
|
+
<td>
|
279
|
+
<%= allocation.klass_name %>
|
280
|
+
</td>
|
281
|
+
<td>
|
282
|
+
<%= "#{allocation.count} (#{allocation.memory} Bytes)" %>
|
283
|
+
</td>
|
284
|
+
<td>
|
285
|
+
<%= "#{allocation.source_file}:#{allocation.line}" %>
|
286
|
+
</td>
|
287
|
+
</tr>
|
288
|
+
<% end %>
|
289
|
+
</table>
|
290
|
+
|
291
|
+
</td>
|
292
|
+
</tr>
|
293
|
+
<% end %>
|
294
|
+
|
295
|
+
<!-- Children -->
|
296
|
+
<% for callee in method.callees.sort_by(&:total_time).reverse
|
297
|
+
next if min_time && callee.total_time < min_time %>
|
298
|
+
<tr>
|
299
|
+
<td> </td>
|
300
|
+
<td> </td>
|
301
|
+
<td><%= sprintf("%.2f", callee.total_time) %></td>
|
302
|
+
<td><%= sprintf("%.2f", callee.self_time) %></td>
|
303
|
+
<td><%= sprintf("%.2f", callee.wait_time) %></td>
|
304
|
+
<td><%= sprintf("%.2f", callee.children_time) %></td>
|
305
|
+
<td><%= "#{callee.called}/#{callee.target.called}" %></td>
|
306
|
+
<td class="method_name"><%= create_link(thread, total_time, callee.target) %></td>
|
307
|
+
<% if @result.track_allocations? %>
|
308
|
+
<td>-</td>
|
309
|
+
<% end %>
|
310
|
+
<td><%= file_link(callee.source_file, callee.line) %>
|
311
|
+
</tr>
|
312
|
+
<% end %>
|
313
|
+
|
314
|
+
<!-- Create divider row -->
|
315
|
+
<tr class="break">
|
316
|
+
<td colspan="10"></td>
|
317
|
+
</tr>
|
318
|
+
<% end %>
|
319
|
+
</tbody>
|
320
|
+
<tfoot>
|
321
|
+
<tr>
|
322
|
+
<td colspan="9">* indicates recursively called methods</td>
|
323
|
+
</tr>
|
324
|
+
</tfoot>
|
325
|
+
</table>
|
326
|
+
<% end %>
|
327
|
+
</div>
|
328
|
+
|
329
|
+
<script type="application/javascript">
|
330
|
+
function toggleAllocations(element)
|
331
|
+
{
|
332
|
+
if (element.style.display == 'none')
|
333
|
+
element.style.display = 'block'
|
334
|
+
else
|
335
|
+
element.style.display = 'none'
|
336
|
+
}
|
337
|
+
|
338
|
+
function onClick(event)
|
339
|
+
{
|
340
|
+
if (event.target.tagName == 'A' && event.target.classList.contains('allocations'))
|
341
|
+
{
|
342
|
+
var url = new URL(event.target.href)
|
343
|
+
var element = document.querySelector(url.hash)
|
344
|
+
toggleAllocations(element)
|
345
|
+
event.preventDefault()
|
346
|
+
}
|
347
|
+
}
|
348
|
+
|
349
|
+
window.addEventListener('DOMContentLoaded', function(event)
|
350
|
+
{
|
351
|
+
document.addEventListener('click', onClick)
|
352
|
+
})
|
353
|
+
|
354
|
+
</script>
|
355
|
+
</body>
|
356
|
+
</html>
|
data/lib/ruby-prof/call_info.rb
CHANGED
@@ -1,115 +1,57 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
module RubyProf
|
4
|
+
# The CallInfo class is used to track the relationships between methods. It is a helper class used by
|
5
|
+
# RubyProf::MethodInfo to keep track of which methods called a given method and which methods a given
|
6
|
+
# method called. Each CallInfo has a parent and target method. You cannot create a CallInfo object directly,
|
7
|
+
# they are generated while running a profile.
|
4
8
|
class CallInfo
|
5
|
-
#
|
6
|
-
|
7
|
-
|
8
|
-
# parent: parent call info (can be nil)
|
9
|
-
# children: array of call info children (can be empty)
|
10
|
-
# target: method info (containing an array of call infos)
|
11
|
-
|
12
|
-
def children_time
|
13
|
-
children.inject(0) do |sum, call_info|
|
14
|
-
sum += call_info.total_time
|
15
|
-
end
|
9
|
+
# The number of times the parent method called the target method
|
10
|
+
def called
|
11
|
+
self.measurement.called
|
16
12
|
end
|
17
13
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
call_info = self
|
22
|
-
|
23
|
-
while call_info
|
24
|
-
methods << call_info.target
|
25
|
-
call_info = call_info.parent
|
26
|
-
end
|
27
|
-
methods.reverse
|
28
|
-
end
|
14
|
+
# The total time resulting from the parent method calling the target method
|
15
|
+
def total_time
|
16
|
+
self.measurement.total_time
|
29
17
|
end
|
30
18
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def root?
|
38
|
-
self.parent.nil?
|
19
|
+
# The self time (of the parent) resulting from the parent method calling the target method
|
20
|
+
def self_time
|
21
|
+
self.measurement.self_time
|
39
22
|
end
|
40
23
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
p = p.parent
|
45
|
-
end
|
46
|
-
p == other
|
24
|
+
# The wait time (of the parent) resulting from the parent method calling the target method
|
25
|
+
def wait_time
|
26
|
+
self.measurement.wait_time
|
47
27
|
end
|
48
28
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
29
|
+
# The time spent in child methods resulting from the parent method calling the target method
|
30
|
+
def children_time
|
31
|
+
self.total_time - self.self_time - self.wait_time
|
32
|
+
end
|
33
|
+
|
34
|
+
# Compares two CallInfo instances. The comparison is based on the CallInfo#parent, CallInfo#target,
|
35
|
+
# and total time.
|
36
|
+
def <=>(other)
|
37
|
+
if self.target == other.target && self.parent == other.parent
|
38
|
+
0
|
39
|
+
elsif self.total_time < other.total_time
|
40
|
+
-1
|
41
|
+
elsif self.total_time > other.total_time
|
42
|
+
1
|
43
|
+
else
|
44
|
+
self.target.full_name <=> other.target.full_name
|
54
45
|
end
|
55
|
-
roots
|
56
46
|
end
|
57
47
|
|
48
|
+
# :nodoc:
|
58
49
|
def to_s
|
59
|
-
"#{
|
50
|
+
"#{parent ? parent.full_name : '<nil>'} - #{target.full_name}"
|
60
51
|
end
|
61
52
|
|
62
53
|
def inspect
|
63
|
-
super + "(#{
|
64
|
-
end
|
65
|
-
|
66
|
-
# eliminate call info from the call tree.
|
67
|
-
# adds self and wait time to parent and attaches called methods to parent.
|
68
|
-
# merges call trees for methods called from both praent end self.
|
69
|
-
def eliminate!
|
70
|
-
# puts "eliminating #{self}"
|
71
|
-
return unless parent
|
72
|
-
parent.add_self_time(self)
|
73
|
-
parent.add_wait_time(self)
|
74
|
-
children.each do |kid|
|
75
|
-
if call = parent.find_call(kid)
|
76
|
-
call.merge_call_tree(kid)
|
77
|
-
else
|
78
|
-
parent.children << kid
|
79
|
-
# $stderr.puts "setting parent of #{kid}\nto #{parent}"
|
80
|
-
kid.parent = parent
|
81
|
-
end
|
82
|
-
end
|
83
|
-
parent.children.delete(self)
|
84
|
-
end
|
85
|
-
|
86
|
-
# find a specific call in list of children. returns nil if not found.
|
87
|
-
# note: there can't be more than one child with a given target method. in other words:
|
88
|
-
# x.children.grep{|y|y.target==m}.size <= 1 for all method infos m and call infos x
|
89
|
-
def find_call(other)
|
90
|
-
matching = children.select { |kid| kid.target == other.target }
|
91
|
-
raise "inconsistent call tree" unless matching.size <= 1
|
92
|
-
matching.first
|
93
|
-
end
|
94
|
-
|
95
|
-
# merge two call trees. adds self, wait, and total time of other to self and merges children of other into children of self.
|
96
|
-
def merge_call_tree(other)
|
97
|
-
# $stderr.puts "merging #{self}\nand #{other}"
|
98
|
-
self.called += other.called
|
99
|
-
add_self_time(other)
|
100
|
-
add_wait_time(other)
|
101
|
-
add_total_time(other)
|
102
|
-
other.children.each do |other_kid|
|
103
|
-
if kid = find_call(other_kid)
|
104
|
-
# $stderr.puts "merging kids"
|
105
|
-
kid.merge_call_tree(other_kid)
|
106
|
-
else
|
107
|
-
other_kid.parent = self
|
108
|
-
children << other_kid
|
109
|
-
end
|
110
|
-
end
|
111
|
-
other.children.clear
|
112
|
-
other.target.call_infos.delete(other)
|
54
|
+
super + "(#{self.to_s})"
|
113
55
|
end
|
114
56
|
end
|
115
57
|
end
|