ruby-prof 2.0.4-x64-mingw-ucrt → 2.0.5-x64-mingw-ucrt
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/CHANGELOG.md +6 -2
- data/lib/4.0/ruby_prof.so +0 -0
- data/lib/ruby-prof/printers/flame_graph_printer.rb +80 -78
- data/lib/ruby-prof/version.rb +1 -1
- metadata +5 -85
- data/Rakefile +0 -98
- data/docs/advanced-usage.md +0 -132
- data/docs/alternatives.md +0 -98
- data/docs/architecture.md +0 -304
- data/docs/best-practices.md +0 -27
- data/docs/getting-started.md +0 -130
- data/docs/history.md +0 -11
- data/docs/index.md +0 -45
- data/docs/profiling-rails.md +0 -64
- data/docs/public/examples/example.rb +0 -33
- data/docs/public/examples/generate_reports.rb +0 -92
- data/docs/public/examples/reports/call_info.txt +0 -27
- data/docs/public/examples/reports/call_stack.html +0 -835
- data/docs/public/examples/reports/callgrind.out +0 -150
- data/docs/public/examples/reports/flame_graph.html +0 -408
- data/docs/public/examples/reports/flat.txt +0 -45
- data/docs/public/examples/reports/graph.dot +0 -129
- data/docs/public/examples/reports/graph.html +0 -1319
- data/docs/public/examples/reports/graph.txt +0 -100
- data/docs/public/examples/reports/graphviz_viewer.html +0 -1
- data/docs/public/images/call_stack.png +0 -0
- data/docs/public/images/class_diagram.png +0 -0
- data/docs/public/images/dot_printer.png +0 -0
- data/docs/public/images/flame_graph.png +0 -0
- data/docs/public/images/flat.png +0 -0
- data/docs/public/images/graph.png +0 -0
- data/docs/public/images/graph_html.png +0 -0
- data/docs/public/images/ruby-prof-logo.svg +0 -1
- data/docs/reports.md +0 -151
- data/docs/stylesheets/extra.css +0 -80
- data/ruby-prof.gemspec +0 -66
- data/test/abstract_printer_test.rb +0 -25
- data/test/alias_test.rb +0 -203
- data/test/call_tree_builder.rb +0 -126
- data/test/call_tree_test.rb +0 -94
- data/test/call_tree_visitor_test.rb +0 -27
- data/test/call_trees_test.rb +0 -66
- data/test/duplicate_names_test.rb +0 -32
- data/test/dynamic_method_test.rb +0 -50
- data/test/enumerable_test.rb +0 -23
- data/test/exceptions_test.rb +0 -24
- data/test/exclude_methods_test.rb +0 -363
- data/test/exclude_threads_test.rb +0 -48
- data/test/fiber_test.rb +0 -195
- data/test/gc_test.rb +0 -104
- data/test/inverse_call_tree_test.rb +0 -174
- data/test/line_number_test.rb +0 -563
- data/test/marshal_test.rb +0 -144
- data/test/measure_allocations.rb +0 -26
- data/test/measure_allocations_test.rb +0 -1511
- data/test/measure_process_time_test.rb +0 -3286
- data/test/measure_times.rb +0 -56
- data/test/measure_wall_time_test.rb +0 -774
- data/test/measurement_test.rb +0 -82
- data/test/merge_test.rb +0 -146
- data/test/method_info_test.rb +0 -100
- data/test/multi_printer_test.rb +0 -52
- data/test/no_method_class_test.rb +0 -15
- data/test/pause_resume_test.rb +0 -171
- data/test/prime.rb +0 -54
- data/test/prime_script.rb +0 -6
- data/test/printer_call_stack_test.rb +0 -28
- data/test/printer_call_tree_test.rb +0 -30
- data/test/printer_flame_graph_test.rb +0 -82
- data/test/printer_flat_test.rb +0 -110
- data/test/printer_graph_html_test.rb +0 -62
- data/test/printer_graph_test.rb +0 -42
- data/test/printers_test.rb +0 -162
- data/test/printing_recursive_graph_test.rb +0 -81
- data/test/profile_test.rb +0 -101
- data/test/rack_test.rb +0 -103
- data/test/recursive_test.rb +0 -796
- data/test/scheduler.rb +0 -367
- data/test/singleton_test.rb +0 -39
- data/test/stack_printer_test.rb +0 -61
- data/test/start_stop_test.rb +0 -106
- data/test/test_helper.rb +0 -24
- data/test/thread_test.rb +0 -229
- data/test/unique_call_path_test.rb +0 -123
- data/test/yarv_test.rb +0 -56
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 52e9bcae8928e06e4f5b63ea914e2e490f2ac6bfdc278141fcb83640b48c8159
|
|
4
|
+
data.tar.gz: '098a6d2e0d5b2baf140d97bf0f5ee3a8bd4c0cebf7b85d05c2e142432176d206'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9fccbc6d3c252f8feb885e1170965152aeb20dc399beec9f0bbce875d959b525a6f8bec0938d7da7b91e36c14f717ff76fc778a57382d562dd7f278d317f848e
|
|
7
|
+
data.tar.gz: 58d3822c64993f5902c783f50b02c55eb529cdf01c6ebc85b9907d7838d9106134fbb6aafeb0a80b530d677eeef262364058285bf4ad9949d43ca9632f480717
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.0.5 (2026-06-21)
|
|
4
|
+
* Fix FlameGraphPrinter crashing with `JSON::NestingError` on deep call trees (issue #353)
|
|
5
|
+
* Fix link to API documentation (issue #351)
|
|
6
|
+
|
|
3
7
|
## 2.0.4 (2026-03-03)
|
|
4
8
|
* Fix NoMethodError when sort_method is nil (issue #349)
|
|
5
9
|
* Fix broken source_code_uri on rubygems.org (issue #350)
|
|
@@ -28,7 +32,7 @@
|
|
|
28
32
|
|
|
29
33
|
### Backwards Incompatible Changes
|
|
30
34
|
* Removed `RubyProf::MEMORY` measurement mode (no longer works on Ruby 4.0+)
|
|
31
|
-
*
|
|
35
|
+
* Remove compatibility API that was scheduled for removal in 2023
|
|
32
36
|
* Printer options now use keyword arguments instead of an options hash. For example:
|
|
33
37
|
```ruby
|
|
34
38
|
# Before:
|
|
@@ -162,7 +166,7 @@ Changes (Charlie Savage):
|
|
|
162
166
|
|
|
163
167
|
* Profiling is significantly faster - 5x in some cases
|
|
164
168
|
* Recursive profiles are finally handled correctly. Yeah!!!
|
|
165
|
-
* Redesigned reports (
|
|
169
|
+
* Redesigned reports (Chris Whitefield)
|
|
166
170
|
* New documentation website (https://ruby-prof.github.io)
|
|
167
171
|
* The ability to measure allocations and memory usage using a standard (unpatched) version of ruby
|
|
168
172
|
* The ability to save and reload profiling results for later analysis
|
|
Binary file
|
|
@@ -1,78 +1,80 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require 'erb'
|
|
4
|
-
require 'json'
|
|
5
|
-
|
|
6
|
-
module RubyProf
|
|
7
|
-
# Prints a HTML flame graph visualization of the call tree.
|
|
8
|
-
#
|
|
9
|
-
# To use the printer:
|
|
10
|
-
#
|
|
11
|
-
# result = RubyProf.profile do
|
|
12
|
-
# [code to profile]
|
|
13
|
-
# end
|
|
14
|
-
#
|
|
15
|
-
# printer = RubyProf::FlameGraphPrinter.new(result)
|
|
16
|
-
# printer.print(STDOUT)
|
|
17
|
-
|
|
18
|
-
class FlameGraphPrinter < AbstractPrinter
|
|
19
|
-
include ERB::Util
|
|
20
|
-
|
|
21
|
-
# Specify print options.
|
|
22
|
-
#
|
|
23
|
-
# output - Any IO object, including STDOUT or a file.
|
|
24
|
-
#
|
|
25
|
-
# Keyword arguments:
|
|
26
|
-
# title: - a String to override the default "ruby-prof flame graph"
|
|
27
|
-
# title of the report.
|
|
28
|
-
#
|
|
29
|
-
# Also accepts min_percent:, max_percent:, filter_by:, and sort_method:
|
|
30
|
-
# from AbstractPrinter.
|
|
31
|
-
def print(output = STDOUT, title: "ruby-prof flame graph",
|
|
32
|
-
min_percent: 0, max_percent: 100, filter_by: :self_time, sort_method: nil, max_depth: nil, **)
|
|
33
|
-
@min_percent = min_percent
|
|
34
|
-
@max_percent = max_percent
|
|
35
|
-
@filter_by = filter_by
|
|
36
|
-
@sort_method = sort_method
|
|
37
|
-
@max_depth = max_depth
|
|
38
|
-
@title = title
|
|
39
|
-
output << ERB.new(self.template).result(binding)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
attr_reader :title
|
|
43
|
-
|
|
44
|
-
def build_flame_data(call_tree, depth = 0)
|
|
45
|
-
node = {
|
|
46
|
-
name: call_tree.target.full_name,
|
|
47
|
-
value: call_tree.total_time,
|
|
48
|
-
self_value: call_tree.self_time,
|
|
49
|
-
called: call_tree.called,
|
|
50
|
-
children: []
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if @max_depth.nil? || depth < @max_depth
|
|
54
|
-
call_tree.children.each do |child|
|
|
55
|
-
node[:children] << build_flame_data(child, depth + 1)
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
node
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def flame_data_json
|
|
63
|
-
threads = @result.threads.map do |thread|
|
|
64
|
-
{
|
|
65
|
-
id: thread.id,
|
|
66
|
-
fiber_id: thread.fiber_id,
|
|
67
|
-
total_time: thread.total_time,
|
|
68
|
-
data: build_flame_data(thread.call_tree)
|
|
69
|
-
}
|
|
70
|
-
end
|
|
71
|
-
JSON
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
end
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'erb'
|
|
4
|
+
require 'json'
|
|
5
|
+
|
|
6
|
+
module RubyProf
|
|
7
|
+
# Prints a HTML flame graph visualization of the call tree.
|
|
8
|
+
#
|
|
9
|
+
# To use the printer:
|
|
10
|
+
#
|
|
11
|
+
# result = RubyProf.profile do
|
|
12
|
+
# [code to profile]
|
|
13
|
+
# end
|
|
14
|
+
#
|
|
15
|
+
# printer = RubyProf::FlameGraphPrinter.new(result)
|
|
16
|
+
# printer.print(STDOUT)
|
|
17
|
+
|
|
18
|
+
class FlameGraphPrinter < AbstractPrinter
|
|
19
|
+
include ERB::Util
|
|
20
|
+
|
|
21
|
+
# Specify print options.
|
|
22
|
+
#
|
|
23
|
+
# output - Any IO object, including STDOUT or a file.
|
|
24
|
+
#
|
|
25
|
+
# Keyword arguments:
|
|
26
|
+
# title: - a String to override the default "ruby-prof flame graph"
|
|
27
|
+
# title of the report.
|
|
28
|
+
#
|
|
29
|
+
# Also accepts min_percent:, max_percent:, filter_by:, and sort_method:
|
|
30
|
+
# from AbstractPrinter.
|
|
31
|
+
def print(output = STDOUT, title: "ruby-prof flame graph",
|
|
32
|
+
min_percent: 0, max_percent: 100, filter_by: :self_time, sort_method: nil, max_depth: nil, **)
|
|
33
|
+
@min_percent = min_percent
|
|
34
|
+
@max_percent = max_percent
|
|
35
|
+
@filter_by = filter_by
|
|
36
|
+
@sort_method = sort_method
|
|
37
|
+
@max_depth = max_depth
|
|
38
|
+
@title = title
|
|
39
|
+
output << ERB.new(self.template).result(binding)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
attr_reader :title
|
|
43
|
+
|
|
44
|
+
def build_flame_data(call_tree, depth = 0)
|
|
45
|
+
node = {
|
|
46
|
+
name: call_tree.target.full_name,
|
|
47
|
+
value: call_tree.total_time,
|
|
48
|
+
self_value: call_tree.self_time,
|
|
49
|
+
called: call_tree.called,
|
|
50
|
+
children: []
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if @max_depth.nil? || depth < @max_depth
|
|
54
|
+
call_tree.children.each do |child|
|
|
55
|
+
node[:children] << build_flame_data(child, depth + 1)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
node
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def flame_data_json
|
|
63
|
+
threads = @result.threads.map do |thread|
|
|
64
|
+
{
|
|
65
|
+
id: thread.id,
|
|
66
|
+
fiber_id: thread.fiber_id,
|
|
67
|
+
total_time: thread.total_time,
|
|
68
|
+
data: build_flame_data(thread.call_tree)
|
|
69
|
+
}
|
|
70
|
+
end
|
|
71
|
+
# Disable JSON nesting limit (default 100) so deep call trees serialize.
|
|
72
|
+
# See https://github.com/ruby-prof/ruby-prof/issues/353
|
|
73
|
+
JSON.generate(threads, max_nesting: false)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def template
|
|
77
|
+
open_asset('flame_graph_printer.html.erb')
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
data/lib/ruby-prof/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby-prof
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.5
|
|
5
5
|
platform: x64-mingw-ucrt
|
|
6
6
|
authors:
|
|
7
7
|
- Shugo Maeda, Charlie Savage, Roger Pack, Stefan Kaes
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-
|
|
10
|
+
date: 2026-06-21 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: base64
|
|
@@ -96,38 +96,8 @@ files:
|
|
|
96
96
|
- CHANGELOG.md
|
|
97
97
|
- LICENSE
|
|
98
98
|
- README.md
|
|
99
|
-
- Rakefile
|
|
100
99
|
- bin/ruby-prof
|
|
101
100
|
- bin/ruby-prof-check-trace
|
|
102
|
-
- docs/advanced-usage.md
|
|
103
|
-
- docs/alternatives.md
|
|
104
|
-
- docs/architecture.md
|
|
105
|
-
- docs/best-practices.md
|
|
106
|
-
- docs/getting-started.md
|
|
107
|
-
- docs/history.md
|
|
108
|
-
- docs/index.md
|
|
109
|
-
- docs/profiling-rails.md
|
|
110
|
-
- docs/public/examples/example.rb
|
|
111
|
-
- docs/public/examples/generate_reports.rb
|
|
112
|
-
- docs/public/examples/reports/call_info.txt
|
|
113
|
-
- docs/public/examples/reports/call_stack.html
|
|
114
|
-
- docs/public/examples/reports/callgrind.out
|
|
115
|
-
- docs/public/examples/reports/flame_graph.html
|
|
116
|
-
- docs/public/examples/reports/flat.txt
|
|
117
|
-
- docs/public/examples/reports/graph.dot
|
|
118
|
-
- docs/public/examples/reports/graph.html
|
|
119
|
-
- docs/public/examples/reports/graph.txt
|
|
120
|
-
- docs/public/examples/reports/graphviz_viewer.html
|
|
121
|
-
- docs/public/images/call_stack.png
|
|
122
|
-
- docs/public/images/class_diagram.png
|
|
123
|
-
- docs/public/images/dot_printer.png
|
|
124
|
-
- docs/public/images/flame_graph.png
|
|
125
|
-
- docs/public/images/flat.png
|
|
126
|
-
- docs/public/images/graph.png
|
|
127
|
-
- docs/public/images/graph_html.png
|
|
128
|
-
- docs/public/images/ruby-prof-logo.svg
|
|
129
|
-
- docs/reports.md
|
|
130
|
-
- docs/stylesheets/extra.css
|
|
131
101
|
- ext/ruby_prof/extconf.rb
|
|
132
102
|
- ext/ruby_prof/rp_allocation.c
|
|
133
103
|
- ext/ruby_prof/rp_allocation.h
|
|
@@ -152,6 +122,7 @@ files:
|
|
|
152
122
|
- ext/ruby_prof/ruby_prof.h
|
|
153
123
|
- ext/ruby_prof/vc/ruby_prof.sln
|
|
154
124
|
- ext/ruby_prof/vc/ruby_prof.vcxproj
|
|
125
|
+
- lib/4.0/ruby_prof.so
|
|
155
126
|
- lib/ruby-prof.rb
|
|
156
127
|
- lib/ruby-prof/assets/call_stack_printer.html.erb
|
|
157
128
|
- lib/ruby-prof/assets/call_stack_printer.png
|
|
@@ -178,56 +149,6 @@ files:
|
|
|
178
149
|
- lib/ruby-prof/thread.rb
|
|
179
150
|
- lib/ruby-prof/version.rb
|
|
180
151
|
- lib/unprof.rb
|
|
181
|
-
- ruby-prof.gemspec
|
|
182
|
-
- test/abstract_printer_test.rb
|
|
183
|
-
- test/alias_test.rb
|
|
184
|
-
- test/call_tree_builder.rb
|
|
185
|
-
- test/call_tree_test.rb
|
|
186
|
-
- test/call_tree_visitor_test.rb
|
|
187
|
-
- test/call_trees_test.rb
|
|
188
|
-
- test/duplicate_names_test.rb
|
|
189
|
-
- test/dynamic_method_test.rb
|
|
190
|
-
- test/enumerable_test.rb
|
|
191
|
-
- test/exceptions_test.rb
|
|
192
|
-
- test/exclude_methods_test.rb
|
|
193
|
-
- test/exclude_threads_test.rb
|
|
194
|
-
- test/fiber_test.rb
|
|
195
|
-
- test/gc_test.rb
|
|
196
|
-
- test/inverse_call_tree_test.rb
|
|
197
|
-
- test/line_number_test.rb
|
|
198
|
-
- test/marshal_test.rb
|
|
199
|
-
- test/measure_allocations.rb
|
|
200
|
-
- test/measure_allocations_test.rb
|
|
201
|
-
- test/measure_process_time_test.rb
|
|
202
|
-
- test/measure_times.rb
|
|
203
|
-
- test/measure_wall_time_test.rb
|
|
204
|
-
- test/measurement_test.rb
|
|
205
|
-
- test/merge_test.rb
|
|
206
|
-
- test/method_info_test.rb
|
|
207
|
-
- test/multi_printer_test.rb
|
|
208
|
-
- test/no_method_class_test.rb
|
|
209
|
-
- test/pause_resume_test.rb
|
|
210
|
-
- test/prime.rb
|
|
211
|
-
- test/prime_script.rb
|
|
212
|
-
- test/printer_call_stack_test.rb
|
|
213
|
-
- test/printer_call_tree_test.rb
|
|
214
|
-
- test/printer_flame_graph_test.rb
|
|
215
|
-
- test/printer_flat_test.rb
|
|
216
|
-
- test/printer_graph_html_test.rb
|
|
217
|
-
- test/printer_graph_test.rb
|
|
218
|
-
- test/printers_test.rb
|
|
219
|
-
- test/printing_recursive_graph_test.rb
|
|
220
|
-
- test/profile_test.rb
|
|
221
|
-
- test/rack_test.rb
|
|
222
|
-
- test/recursive_test.rb
|
|
223
|
-
- test/scheduler.rb
|
|
224
|
-
- test/singleton_test.rb
|
|
225
|
-
- test/stack_printer_test.rb
|
|
226
|
-
- test/start_stop_test.rb
|
|
227
|
-
- test/test_helper.rb
|
|
228
|
-
- test/thread_test.rb
|
|
229
|
-
- test/unique_call_path_test.rb
|
|
230
|
-
- test/yarv_test.rb
|
|
231
152
|
homepage: https://github.com/ruby-prof/ruby-prof
|
|
232
153
|
licenses:
|
|
233
154
|
- BSD-2-Clause
|
|
@@ -235,7 +156,7 @@ metadata:
|
|
|
235
156
|
bug_tracker_uri: https://github.com/ruby-prof/ruby-prof/issues
|
|
236
157
|
changelog_uri: https://github.com/ruby-prof/ruby-prof/blob/master/CHANGELOG.md
|
|
237
158
|
documentation_uri: https://ruby-prof.github.io/
|
|
238
|
-
source_code_uri: https://github.com/ruby-prof/ruby-prof/tree/2.0.
|
|
159
|
+
source_code_uri: https://github.com/ruby-prof/ruby-prof/tree/2.0.5
|
|
239
160
|
rdoc_options: []
|
|
240
161
|
require_paths:
|
|
241
162
|
- lib
|
|
@@ -253,5 +174,4 @@ requirements: []
|
|
|
253
174
|
rubygems_version: 4.0.6
|
|
254
175
|
specification_version: 4
|
|
255
176
|
summary: Fast Ruby profiler
|
|
256
|
-
test_files:
|
|
257
|
-
- test/test_helper.rb
|
|
177
|
+
test_files: []
|
data/Rakefile
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require "rubygems/package_task"
|
|
4
|
-
require "rake/extensiontask"
|
|
5
|
-
require "rake/testtask"
|
|
6
|
-
require "rdoc/task"
|
|
7
|
-
require "date"
|
|
8
|
-
require "rake/clean"
|
|
9
|
-
|
|
10
|
-
# To release a version of ruby-prof:
|
|
11
|
-
# * Update lib/ruby-prof/version.rb
|
|
12
|
-
# * Update CHANGES
|
|
13
|
-
# * git commit to commit files
|
|
14
|
-
# * rake clobber to remove extra files
|
|
15
|
-
# * rake compile to build windows gems
|
|
16
|
-
# * rake package to create the gems
|
|
17
|
-
# * Tag the release (git tag 0.10.1)
|
|
18
|
-
# * Push to ruybgems.org (gem push pkg/<gem files>)
|
|
19
|
-
|
|
20
|
-
GEM_NAME = 'ruby-prof'
|
|
21
|
-
SO_NAME = 'ruby_prof'
|
|
22
|
-
|
|
23
|
-
default_spec = Gem::Specification.load("#{GEM_NAME}.gemspec")
|
|
24
|
-
|
|
25
|
-
# specify which versions/builds to cross compile
|
|
26
|
-
Rake::ExtensionTask.new do |ext|
|
|
27
|
-
ext.gem_spec = default_spec
|
|
28
|
-
ext.name = SO_NAME
|
|
29
|
-
ext.ext_dir = "ext/#{SO_NAME}"
|
|
30
|
-
ext.lib_dir = "lib/#{Gem::Version.new(RUBY_VERSION).segments[0..1].join('.')}"
|
|
31
|
-
ext.cross_compile = true
|
|
32
|
-
ext.cross_platform = ['x64-mingw32']
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
# Rake task to build the default package
|
|
36
|
-
Gem::PackageTask.new(default_spec) do |pkg|
|
|
37
|
-
pkg.need_tar = true
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# make sure rdoc has been built when packaging
|
|
41
|
-
# why do we ship rdoc as part of the gem?
|
|
42
|
-
Rake::Task[:package].enhance [:rdoc]
|
|
43
|
-
|
|
44
|
-
# Setup Windows Gem
|
|
45
|
-
if RUBY_PLATFORM.match(/mswin|mingw/)
|
|
46
|
-
# Windows specification
|
|
47
|
-
win_spec = default_spec.clone
|
|
48
|
-
win_spec.platform = Gem::Platform::CURRENT
|
|
49
|
-
win_spec.files += Dir.glob('lib/**/*.so')
|
|
50
|
-
|
|
51
|
-
# Unset extensions
|
|
52
|
-
win_spec.extensions = nil
|
|
53
|
-
|
|
54
|
-
# Rake task to build the windows package
|
|
55
|
-
Gem::PackageTask.new(win_spec) do |pkg|
|
|
56
|
-
pkg.need_tar = false
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
# --------- RDoc Documentation ------
|
|
61
|
-
desc "Generate rdoc documentation"
|
|
62
|
-
RDoc::Task.new("rdoc") do |rdoc|
|
|
63
|
-
rdoc.rdoc_dir = 'doc'
|
|
64
|
-
rdoc.title = "ruby-prof"
|
|
65
|
-
# Show source inline with line numbers
|
|
66
|
-
rdoc.options << "--line-numbers"
|
|
67
|
-
# Make the readme file the start page for the generated html
|
|
68
|
-
rdoc.options << '--main' << 'README.md'
|
|
69
|
-
rdoc.rdoc_files.include('bin/*',
|
|
70
|
-
'doc/*.rdoc',
|
|
71
|
-
'lib/**/*.rb',
|
|
72
|
-
'ext/ruby_prof/*.c',
|
|
73
|
-
'ext/ruby_prof/*.h',
|
|
74
|
-
'README.md',
|
|
75
|
-
'LICENSE')
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
task :default => :test
|
|
79
|
-
|
|
80
|
-
for file in Dir['lib/**/*.{o,so,bundle}']
|
|
81
|
-
CLEAN.include file
|
|
82
|
-
end
|
|
83
|
-
for file in Dir['doc/**/*.{txt,dat,png,html}']
|
|
84
|
-
CLEAN.include file
|
|
85
|
-
end
|
|
86
|
-
CLEAN.reject!{|f| !File.exist?(f)}
|
|
87
|
-
task :clean do
|
|
88
|
-
# remove tmp dir contents completely after cleaning
|
|
89
|
-
FileUtils.rm_rf('tmp/*')
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
desc 'Run the ruby-prof test suite'
|
|
93
|
-
Rake::TestTask.new do |t|
|
|
94
|
-
t.libs += %w(lib ext test)
|
|
95
|
-
t.test_files = Dir['test/**_test.rb']
|
|
96
|
-
t.verbose = true
|
|
97
|
-
t.warning = true
|
|
98
|
-
end
|
data/docs/advanced-usage.md
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
# Advanced Usage
|
|
2
|
-
|
|
3
|
-
This section describes advanced usage of ruby-prof. Additional documentation for every class is also [available](index.md#api-documentation). For workflow guidance, see [Best Practices](best-practices.md).
|
|
4
|
-
|
|
5
|
-
## Profiling Options
|
|
6
|
-
|
|
7
|
-
ruby-prof understands the following options when profiling code:
|
|
8
|
-
|
|
9
|
-
**measure_mode** - What ruby-prof should measure. For more information see the [Measurement Mode](#measurement-mode) section.
|
|
10
|
-
|
|
11
|
-
**track_allocations** - Tracks each object location, including the object class and source file location. For more information see the [Allocation Tracking](#allocation-tracking) section.
|
|
12
|
-
|
|
13
|
-
**exclude_threads** - Array of threads which should not be profiled. For more information see the [Thread Inclusion/Exclusion](#thread-inclusionexclusion) section.
|
|
14
|
-
|
|
15
|
-
**include_threads** - Array of threads which should be profiled. All other threads will be ignored. For more information see the [Thread Inclusion/Exclusion](#thread-inclusionexclusion) section.
|
|
16
|
-
|
|
17
|
-
**allow_exceptions** - Whether to raise exceptions encountered during profiling, or to suppress them. Defaults to false.
|
|
18
|
-
|
|
19
|
-
**exclude_common** - Automatically calls `exclude_common_methods!` to exclude commonly cluttering methods. Defaults to false. For more information see the [Method Exclusion](#method-exclusion) section.
|
|
20
|
-
|
|
21
|
-
## Measurement Mode
|
|
22
|
-
|
|
23
|
-
The measurement mode determines what ruby-prof measures when profiling code. Supported measurements are:
|
|
24
|
-
|
|
25
|
-
### Wall Time
|
|
26
|
-
|
|
27
|
-
Wall time measures the real-world time elapsed between any two moments in seconds. If there are other processes concurrently running on the system that use significant CPU or disk time during a profiling run then the reported results will be larger than expected. On Windows, wall time is measured using `QueryPerformanceCounter` and on other platforms by `clock_gettime(CLOCK_MONOTONIC)`. Use `RubyProf::WALL_TIME` to select this mode.
|
|
28
|
-
|
|
29
|
-
### Process Time
|
|
30
|
-
|
|
31
|
-
Process time measures the time used by a process between any two moments in seconds. It is unaffected by other processes concurrently running on the system. Remember with process time that calls to methods like sleep will not be included in profiling results. On Windows, process time is measured using `GetProcessTimes` and on other platforms by `clock_gettime`. Use `RubyProf::PROCESS_TIME` to select this mode.
|
|
32
|
-
|
|
33
|
-
### Object Allocations
|
|
34
|
-
|
|
35
|
-
Object allocations measures how many objects each method in a program allocates. Measurements are done via Ruby's `RUBY_INTERNAL_EVENT_NEWOBJ` trace event, counting each new object created (excluding internal `T_IMEMO` objects). Use `RubyProf::ALLOCATIONS` to select this mode.
|
|
36
|
-
|
|
37
|
-
To set the measurement mode:
|
|
38
|
-
|
|
39
|
-
```ruby
|
|
40
|
-
profile = RubyProf::Profile.new(measure_mode: RubyProf::WALL_TIME)
|
|
41
|
-
profile = RubyProf::Profile.new(measure_mode: RubyProf::PROCESS_TIME)
|
|
42
|
-
profile = RubyProf::Profile.new(measure_mode: RubyProf::ALLOCATIONS)
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
The default value is `RubyProf::WALL_TIME`. You may also specify the measure mode by using the `RUBY_PROF_MEASURE_MODE` environment variable:
|
|
46
|
-
|
|
47
|
-
```
|
|
48
|
-
export RUBY_PROF_MEASURE_MODE=wall
|
|
49
|
-
export RUBY_PROF_MEASURE_MODE=process
|
|
50
|
-
export RUBY_PROF_MEASURE_MODE=allocations
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
## Allocation Tracking
|
|
54
|
-
|
|
55
|
-
ruby-prof also has the ability to track object allocations. This functionality can be turned on via the track_allocations option:
|
|
56
|
-
|
|
57
|
-
```ruby
|
|
58
|
-
require 'ruby-prof'
|
|
59
|
-
|
|
60
|
-
RubyProf::Profile.profile(track_allocations: true) do
|
|
61
|
-
...
|
|
62
|
-
end
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
Note the `RubyProf::ALLOCATIONS` measure mode is slightly different than tracking allocations. The measurement mode provides high level information about the number of allocations performed in each method. In contrast, tracking allocations provides detailed information about allocation type, count, and source location. Currently, to see allocations results you must use the `RubyProf::GraphHtmlPrinter`.
|
|
66
|
-
|
|
67
|
-
## Thread Inclusion/Exclusion
|
|
68
|
-
|
|
69
|
-
ruby-prof can profile multiple threads. Sometimes this can be overwhelming. For example, assume you want to determine why your tests are running slowly. If you are using minitest, it can run tests in parallel by spawning worker threads (to force a single worker, set `N=0` when running tests). Thus, ruby-prof provides two options to specify which threads should be profiled:
|
|
70
|
-
|
|
71
|
-
**exclude_threads** - Array of threads which should not be profiled.
|
|
72
|
-
|
|
73
|
-
**include_threads** - Array of threads which should be profiled. All other threads will be ignored.
|
|
74
|
-
|
|
75
|
-
## Method Exclusion
|
|
76
|
-
|
|
77
|
-
ruby-prof supports excluding specific methods and threads from profiling results. This is useful for reducing connectivity in the call graph, making it easier to identify the source of performance problems when using a graph printer. For example, consider `Integer#times`: it's hardly ever useful to know how much time is spent in the method itself. We are more interested in how much the passed in block contributes to the time spent in the method which contains the `Integer#times` call. The effect on collected metrics are identical to eliminating methods from the profiling result in a post process step.
|
|
78
|
-
|
|
79
|
-
```ruby
|
|
80
|
-
profile = RubyProf::Profile.new(...)
|
|
81
|
-
profile.exclude_methods!(Integer, :times, ...)
|
|
82
|
-
profile.start
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
A convenience method is provided to exclude a large number of methods which usually clutter up profiles:
|
|
86
|
-
|
|
87
|
-
```ruby
|
|
88
|
-
profile.exclude_common_methods!
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
However, this is a somewhat opinionated method collection. It's usually better to view it as an inspiration instead of using it directly (see [exclude_common_methods.rb](https://github.com/ruby-prof/ruby-prof/blob/e087b7d7ca11eecf1717d95a5c5fea1e36ea3136/lib/ruby-prof/profile/exclude_common_methods.rb)).
|
|
92
|
-
|
|
93
|
-
## Merging Threads and Fibers
|
|
94
|
-
|
|
95
|
-
ruby-prof profiles each thread and fiber separately. A common design pattern is to have a main thread delegate work to background threads or fibers. Examples include web servers such as Puma and Falcon, as well as code that uses `Enumerator`, `Fiber.new`, or async libraries.
|
|
96
|
-
|
|
97
|
-
Understanding profiling results can be very difficult when there are many threads or fibers because each one appears as a separate entry in the output. To help with this, ruby-prof includes the ability to merge results for threads and fibers that start with the same root method. In the best case, this can collapse results into just two entries - one for the parent thread and one for all workers.
|
|
98
|
-
|
|
99
|
-
Note the collapsed results show the sum of times for all merged threads/fibers. For example, assume there are 10 worker fibers that each took 5 seconds to run. The single merged entry will show a total time of 50 seconds.
|
|
100
|
-
|
|
101
|
-
To merge threads and fibers:
|
|
102
|
-
|
|
103
|
-
```ruby
|
|
104
|
-
profile = RubyProf::Profile.profile do
|
|
105
|
-
...
|
|
106
|
-
end
|
|
107
|
-
profile.merge!
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
This is also supported in the Rack adapter via the `merge_fibers` option:
|
|
111
|
-
|
|
112
|
-
```ruby
|
|
113
|
-
config.middleware.use Rack::RubyProf, path: Rails.root.join("tmp/profile"), merge_fibers: true
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
## Saving Results
|
|
117
|
-
|
|
118
|
-
It can be helpful to save the results of a profiling run for later analysis. Results can be saved using Ruby's [marshal](https://docs.ruby-lang.org/en/master/Marshal.html) library.
|
|
119
|
-
|
|
120
|
-
```ruby
|
|
121
|
-
profile_1 = RubyProf::Profile.profile do
|
|
122
|
-
...
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
# Save the results
|
|
126
|
-
data = Marshal.dump(profile_1)
|
|
127
|
-
|
|
128
|
-
# Sometime later load the results
|
|
129
|
-
profile_2 = Marshal.load(data)
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
**!!!WARNING!!!** - Only load ruby-prof profiles that you know are safe. Demarshaling data can lead to arbitrary code execution and thus can be [dangerous](https://docs.ruby-lang.org/en/master/Marshal.html#module-Marshal-label-Security+considerations).
|
data/docs/alternatives.md
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
# Comparison with Other Profilers
|
|
2
|
-
|
|
3
|
-
Ruby has several excellent profiling tools, each with different strengths. This page compares ruby-prof with three popular alternatives to help you choose the right tool for your needs.
|
|
4
|
-
|
|
5
|
-
## Tracing vs Sampling
|
|
6
|
-
|
|
7
|
-
The most important distinction between profilers is **tracing** vs **sampling**:
|
|
8
|
-
|
|
9
|
-
- **Tracing profilers** (ruby-prof) instrument every method call and return. This provides exact call counts and complete call graphs, but adds overhead to every method invocation.
|
|
10
|
-
- **Sampling profilers** (stackprof, rbspy, vernier) periodically capture stack snapshots. This has much lower overhead but may miss short-lived method calls.
|
|
11
|
-
|
|
12
|
-
## Overview
|
|
13
|
-
|
|
14
|
-
The table below compares ruby-prof with [stackprof](https://github.com/tmm1/stackprof), [rbspy](https://github.com/rbspy/rbspy), and [vernier](https://github.com/jhawthorn/vernier) — the three most popular sampling profilers for Ruby.
|
|
15
|
-
|
|
16
|
-
| | ruby-prof | stackprof | rbspy | vernier |
|
|
17
|
-
|---|---|---|---|---|
|
|
18
|
-
| **Type** | Tracing | Sampling | Sampling | Sampling |
|
|
19
|
-
| **Implementation** | C extension (TracePoint API) | C extension (signals) | External Rust binary | C extension (signals) |
|
|
20
|
-
| **Code changes** | None ([CLI](getting-started.md#command-line)) or minimal | Minimal | None | Minimal |
|
|
21
|
-
| **Ruby versions** | All, since 2006 (currently 3.2+) | 2.2+ | 1.9.3+ | 3.2.1+ |
|
|
22
|
-
| **OS support** | Linux, macOS, Windows | Linux | Linux, macOS, Windows, FreeBSD | Linux, macOS |
|
|
23
|
-
|
|
24
|
-
## Measurement Capabilities
|
|
25
|
-
|
|
26
|
-
| | ruby-prof | stackprof | rbspy | vernier |
|
|
27
|
-
|---|---|---|---|---|
|
|
28
|
-
| **Wall time** | Yes | Yes | Yes | Yes |
|
|
29
|
-
| **CPU/Process time** | Yes | Yes | No | No |
|
|
30
|
-
| **Allocations** | Yes | Yes | No | Yes |
|
|
31
|
-
| **GVL visibility** | No | No | No | Yes |
|
|
32
|
-
| **GC pauses** | No | No | No | Yes |
|
|
33
|
-
| **Retained memory** | No | No | No | Yes |
|
|
34
|
-
| **Multi-thread** | Yes | No | No | Yes |
|
|
35
|
-
| **Fibers** | Yes | No | No | No |
|
|
36
|
-
|
|
37
|
-
## Report Formats
|
|
38
|
-
|
|
39
|
-
| | ruby-prof | stackprof | rbspy | vernier |
|
|
40
|
-
|---|---|---|---|---|
|
|
41
|
-
| **Flat/Summary** | Yes | Yes | Yes | No |
|
|
42
|
-
| **Call graph** | Yes (text + HTML) | No | No | No |
|
|
43
|
-
| **Flame graph** | Yes (HTML) | Yes | Yes (SVG) | Yes (Firefox Profiler) |
|
|
44
|
-
| **Call stack** | Yes (HTML) | No | No | No |
|
|
45
|
-
| **Callgrind** | Yes | No | Yes | No |
|
|
46
|
-
| **Graphviz dot** | Yes | Yes | No | No |
|
|
47
|
-
|
|
48
|
-
## When to Use Each
|
|
49
|
-
|
|
50
|
-
### ruby-prof
|
|
51
|
-
|
|
52
|
-
ruby-prof is the longest-standing Ruby profiler, with its [first](./history.md) release in 2005. It has been continuously maintained for nearly two decades, evolving alongside Ruby itself from 1.8 through 4.0. Over that time it has supported every major Ruby version and platform, including Windows — a rarity among Ruby C extensions.
|
|
53
|
-
|
|
54
|
-
Being a tracing profiler, ruby-prof provides *exact* information about your program. It tracks every thread, every fiber and every method call. It shines with its support for multiple measurements modes and excellent reporting capabilities.
|
|
55
|
-
|
|
56
|
-
ruby-prof can be used from the [command line](getting-started.md#command-line) with no code changes, or via an API for more control.
|
|
57
|
-
|
|
58
|
-
The biggest downsides of ruby-prof are:
|
|
59
|
-
|
|
60
|
-
* It adds significant overhead for running programs, so is not suitable for production use
|
|
61
|
-
* It must start a Ruby program, it cannot attach to an already running program
|
|
62
|
-
|
|
63
|
-
### stackprof
|
|
64
|
-
|
|
65
|
-
[stackprof](https://github.com/tmm1/stackprof) is a low-overhead, sampling profiler that is good for development. It adds minimal overhead while still providing useful flame graphs and per-line hit counts. A good choice when you want something lightweight and well-established.
|
|
66
|
-
|
|
67
|
-
The biggest downsides of stackprof are:
|
|
68
|
-
|
|
69
|
-
* Single-thread only
|
|
70
|
-
* Linux only for time-based modes
|
|
71
|
-
|
|
72
|
-
### rbspy
|
|
73
|
-
|
|
74
|
-
[rbspy](https://github.com/rbspy/rbspy) is a sampling profiler best for profiling in production or when you cannot modify the application code. As an external process, it attaches to a running Ruby process by PID with zero code changes. It is particularly useful for profiling third-party Ruby applications (Chef, Puppet, etc.), investigating slow test runs, or quick profiling of scripts via `rbspy record ruby my-script.rb`. Supports the widest range of Ruby versions.
|
|
75
|
-
|
|
76
|
-
The biggest downsides of rbspy are:
|
|
77
|
-
|
|
78
|
-
* No allocation profiling
|
|
79
|
-
* No call graph or caller/callee data
|
|
80
|
-
|
|
81
|
-
### vernier
|
|
82
|
-
|
|
83
|
-
[vernier](https://github.com/jhawthorn/vernier) is a sampling profiler best for diagnosing concurrency issues and understanding GVL contention. It is the only Ruby profiler that reports GVL state, GC pauses and idle time. Its Firefox Profiler integration provides rich interactive visualizations with per-thread timelines.
|
|
84
|
-
|
|
85
|
-
The biggest downsides of vernier are:
|
|
86
|
-
|
|
87
|
-
* Requires Ruby 3.2.1+
|
|
88
|
-
* No Windows support
|
|
89
|
-
|
|
90
|
-
### rack-mini-profiler
|
|
91
|
-
|
|
92
|
-
[rack-mini-profiler](https://github.com/MiniProfiler/rack-mini-profiler) is a "batteries-included" profiling tool for Rails and Rack applications. It uses stackprof under the hood for CPU profiling while also supporting memory profiling. It is a good choice if you want an integrated profiling solution that works directly in the browser during development.
|
|
93
|
-
|
|
94
|
-
## Memory Profiling
|
|
95
|
-
|
|
96
|
-
[memory_profiler](https://github.com/SamSaffron/memory_profiler) is another profiler, but it focuses exclusively on memory usage. It uses Ruby's `ObjectSpace` API to track every object allocation during a block of code, recording the source file, line number, object type, and size via `ObjectSpace.memsize_of`. By snapshotting the GC generation before and after, it distinguishes between allocated objects (created during the block) and retained objects (still alive after GC). This makes it useful for finding memory leaks and identifying allocation-heavy code. It's pure Ruby with no C extension, so it works across Ruby versions and platforms.
|
|
97
|
-
|
|
98
|
-
ruby-prof can track allocation counts via its `RubyProf::ALLOCATIONS` mode, but memory_profiler gives deeper insight into memory specifically — object sizes, retained vs allocated, and per-gem breakdowns.
|