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.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -2
  3. data/lib/4.0/ruby_prof.so +0 -0
  4. data/lib/ruby-prof/printers/flame_graph_printer.rb +80 -78
  5. data/lib/ruby-prof/version.rb +1 -1
  6. metadata +5 -85
  7. data/Rakefile +0 -98
  8. data/docs/advanced-usage.md +0 -132
  9. data/docs/alternatives.md +0 -98
  10. data/docs/architecture.md +0 -304
  11. data/docs/best-practices.md +0 -27
  12. data/docs/getting-started.md +0 -130
  13. data/docs/history.md +0 -11
  14. data/docs/index.md +0 -45
  15. data/docs/profiling-rails.md +0 -64
  16. data/docs/public/examples/example.rb +0 -33
  17. data/docs/public/examples/generate_reports.rb +0 -92
  18. data/docs/public/examples/reports/call_info.txt +0 -27
  19. data/docs/public/examples/reports/call_stack.html +0 -835
  20. data/docs/public/examples/reports/callgrind.out +0 -150
  21. data/docs/public/examples/reports/flame_graph.html +0 -408
  22. data/docs/public/examples/reports/flat.txt +0 -45
  23. data/docs/public/examples/reports/graph.dot +0 -129
  24. data/docs/public/examples/reports/graph.html +0 -1319
  25. data/docs/public/examples/reports/graph.txt +0 -100
  26. data/docs/public/examples/reports/graphviz_viewer.html +0 -1
  27. data/docs/public/images/call_stack.png +0 -0
  28. data/docs/public/images/class_diagram.png +0 -0
  29. data/docs/public/images/dot_printer.png +0 -0
  30. data/docs/public/images/flame_graph.png +0 -0
  31. data/docs/public/images/flat.png +0 -0
  32. data/docs/public/images/graph.png +0 -0
  33. data/docs/public/images/graph_html.png +0 -0
  34. data/docs/public/images/ruby-prof-logo.svg +0 -1
  35. data/docs/reports.md +0 -151
  36. data/docs/stylesheets/extra.css +0 -80
  37. data/ruby-prof.gemspec +0 -66
  38. data/test/abstract_printer_test.rb +0 -25
  39. data/test/alias_test.rb +0 -203
  40. data/test/call_tree_builder.rb +0 -126
  41. data/test/call_tree_test.rb +0 -94
  42. data/test/call_tree_visitor_test.rb +0 -27
  43. data/test/call_trees_test.rb +0 -66
  44. data/test/duplicate_names_test.rb +0 -32
  45. data/test/dynamic_method_test.rb +0 -50
  46. data/test/enumerable_test.rb +0 -23
  47. data/test/exceptions_test.rb +0 -24
  48. data/test/exclude_methods_test.rb +0 -363
  49. data/test/exclude_threads_test.rb +0 -48
  50. data/test/fiber_test.rb +0 -195
  51. data/test/gc_test.rb +0 -104
  52. data/test/inverse_call_tree_test.rb +0 -174
  53. data/test/line_number_test.rb +0 -563
  54. data/test/marshal_test.rb +0 -144
  55. data/test/measure_allocations.rb +0 -26
  56. data/test/measure_allocations_test.rb +0 -1511
  57. data/test/measure_process_time_test.rb +0 -3286
  58. data/test/measure_times.rb +0 -56
  59. data/test/measure_wall_time_test.rb +0 -774
  60. data/test/measurement_test.rb +0 -82
  61. data/test/merge_test.rb +0 -146
  62. data/test/method_info_test.rb +0 -100
  63. data/test/multi_printer_test.rb +0 -52
  64. data/test/no_method_class_test.rb +0 -15
  65. data/test/pause_resume_test.rb +0 -171
  66. data/test/prime.rb +0 -54
  67. data/test/prime_script.rb +0 -6
  68. data/test/printer_call_stack_test.rb +0 -28
  69. data/test/printer_call_tree_test.rb +0 -30
  70. data/test/printer_flame_graph_test.rb +0 -82
  71. data/test/printer_flat_test.rb +0 -110
  72. data/test/printer_graph_html_test.rb +0 -62
  73. data/test/printer_graph_test.rb +0 -42
  74. data/test/printers_test.rb +0 -162
  75. data/test/printing_recursive_graph_test.rb +0 -81
  76. data/test/profile_test.rb +0 -101
  77. data/test/rack_test.rb +0 -103
  78. data/test/recursive_test.rb +0 -796
  79. data/test/scheduler.rb +0 -367
  80. data/test/singleton_test.rb +0 -39
  81. data/test/stack_printer_test.rb +0 -61
  82. data/test/start_stop_test.rb +0 -106
  83. data/test/test_helper.rb +0 -24
  84. data/test/thread_test.rb +0 -229
  85. data/test/unique_call_path_test.rb +0 -123
  86. data/test/yarv_test.rb +0 -56
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 848aa4759d3b0388da8b062be538cc88e179153dcaece71467c1015cd2530c72
4
- data.tar.gz: 13fef04d65fb66ce56c0eb32e2d03071f757776e048fcc1c39afdeb2e9af1951
3
+ metadata.gz: 52e9bcae8928e06e4f5b63ea914e2e490f2ac6bfdc278141fcb83640b48c8159
4
+ data.tar.gz: '098a6d2e0d5b2baf140d97bf0f5ee3a8bd4c0cebf7b85d05c2e142432176d206'
5
5
  SHA512:
6
- metadata.gz: d8d37e8bf2dd91c771d570af773e25e3816e1bafbf91972cfb9ce3b30f203c701599e84d1b9b9155a0f06f8c5add085e6691f2c7ed221328408bb7428854b1c5
7
- data.tar.gz: 98a6be45f8b4597ffa66d5ef4f679ce1b99e7e2563853f496c84733c9954dc77a70284ec06d682031119f7069107b7557b628c9ca899059543971d1f6eae7b74
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
- * Rremove compatibility API that was scheduled for removal in 2023
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 (Chirs Whitefield)
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.generate(threads)
72
- end
73
-
74
- def template
75
- open_asset('flame_graph_printer.html.erb')
76
- end
77
- end
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
@@ -1,3 +1,3 @@
1
1
  module RubyProf
2
- VERSION = "2.0.4"
2
+ VERSION = "2.0.5"
3
3
  end
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
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-03-03 00:00:00.000000000 Z
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.4
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
@@ -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.