ruby-prof 2.0.3 → 2.0.5
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 +615 -607
- data/bin/ruby-prof +336 -336
- data/lib/ruby-prof/printers/abstract_printer.rb +143 -143
- data/lib/ruby-prof/printers/flame_graph_printer.rb +80 -78
- data/lib/ruby-prof/version.rb +3 -3
- metadata +4 -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 -99
- 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
|
@@ -1,143 +1,143 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
module RubyProf
|
|
4
|
-
# This is the base class for all Printers. It is never used directly.
|
|
5
|
-
class AbstractPrinter
|
|
6
|
-
# :stopdoc:
|
|
7
|
-
def self.needs_dir?
|
|
8
|
-
false
|
|
9
|
-
end
|
|
10
|
-
# :startdoc:
|
|
11
|
-
|
|
12
|
-
# Create a new printer.
|
|
13
|
-
#
|
|
14
|
-
# result should be the output generated from a profiling run
|
|
15
|
-
def initialize(result)
|
|
16
|
-
@result = result
|
|
17
|
-
@output = nil
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
attr_reader :min_percent, :max_percent, :filter_by, :sort_method
|
|
21
|
-
|
|
22
|
-
# Returns the time format used to show when a profile was run
|
|
23
|
-
def time_format
|
|
24
|
-
'%A, %B %-d at %l:%M:%S %p (%Z)'
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# Prints a report to the provided output.
|
|
28
|
-
#
|
|
29
|
-
# output - Any IO object, including STDOUT or a file.
|
|
30
|
-
# The default value is STDOUT.
|
|
31
|
-
#
|
|
32
|
-
# Keyword arguments:
|
|
33
|
-
# min_percent - Number 0 to 100 that specifies the minimum
|
|
34
|
-
# %self (the methods self time divided by the
|
|
35
|
-
# overall total time) that a method must take
|
|
36
|
-
# for it to be printed out in the report.
|
|
37
|
-
# Default value is 0.
|
|
38
|
-
#
|
|
39
|
-
# max_percent - Number 0 to 100 that specifies the maximum
|
|
40
|
-
# %self for methods to include.
|
|
41
|
-
# Default value is 100.
|
|
42
|
-
#
|
|
43
|
-
# filter_by - Which time metric to use when applying
|
|
44
|
-
# min_percent and max_percent filters.
|
|
45
|
-
# Default value is :self_time.
|
|
46
|
-
#
|
|
47
|
-
# sort_method - Specifies method used for sorting method infos.
|
|
48
|
-
# Available values are :total_time, :self_time,
|
|
49
|
-
# :wait_time, :children_time.
|
|
50
|
-
# Default value depends on the printer.
|
|
51
|
-
def print(output = STDOUT, min_percent: 0, max_percent: 100, filter_by: :self_time, sort_method: nil, max_depth: nil, **)
|
|
52
|
-
@output = output
|
|
53
|
-
@min_percent = min_percent
|
|
54
|
-
@max_percent = max_percent
|
|
55
|
-
@filter_by = filter_by
|
|
56
|
-
@sort_method = sort_method
|
|
57
|
-
@max_depth = max_depth
|
|
58
|
-
print_threads
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def method_location(method)
|
|
62
|
-
if method.source_file
|
|
63
|
-
"#{method.source_file}:#{method.line}"
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def method_href(thread, method)
|
|
68
|
-
h(method.full_name.gsub(/[><#\.\?=:]/,"_") + "_" + thread.fiber_id.to_s)
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def open_asset(file)
|
|
72
|
-
path = File.join(File.expand_path('../../assets', __FILE__), file)
|
|
73
|
-
File.open(path, 'rb').read
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def print_threads
|
|
77
|
-
@result.threads.each do |thread|
|
|
78
|
-
print_thread(thread)
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def print_thread(thread)
|
|
83
|
-
print_header(thread)
|
|
84
|
-
print_methods(thread)
|
|
85
|
-
print_footer(thread)
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def print_header(thread)
|
|
89
|
-
@output << "Measure Mode: %s\n" % @result.measure_mode_string
|
|
90
|
-
@output << "Thread ID: %d\n" % thread.id
|
|
91
|
-
@output << "Fiber ID: %d\n" % thread.fiber_id unless thread.id == thread.fiber_id
|
|
92
|
-
@output << "Total: %0.6f\n" % thread.total_time
|
|
93
|
-
@output << "Sort by: #{sort_method}\n"
|
|
94
|
-
@output << "\n"
|
|
95
|
-
print_column_headers
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def print_column_headers
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
def print_footer(thread)
|
|
102
|
-
metric_data = {
|
|
103
|
-
0 => { label: "time", prefix: "", suffix: "spent" },
|
|
104
|
-
1 => { label: "time", prefix: "", suffix: "spent" },
|
|
105
|
-
2 => { label: "allocations", prefix: "number of ", suffix: "made" },
|
|
106
|
-
3 => { label: "memory", prefix: "", suffix: "used" }
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
metric = metric_data[@result.measure_mode]
|
|
110
|
-
|
|
111
|
-
metric_label = metric[:label]
|
|
112
|
-
metric_suffix = metric[:suffix]
|
|
113
|
-
metric_prefix = metric[:prefix]
|
|
114
|
-
|
|
115
|
-
metric1 = "#{metric_label} #{metric_suffix}"
|
|
116
|
-
metric2 = "#{metric_prefix}#{metric1}"
|
|
117
|
-
metric3 = metric_label
|
|
118
|
-
|
|
119
|
-
# Output the formatted text
|
|
120
|
-
@output << <<~EOT
|
|
121
|
-
|
|
122
|
-
* recursively called methods
|
|
123
|
-
|
|
124
|
-
Columns are:
|
|
125
|
-
|
|
126
|
-
%self - The percentage of #{metric1} by this method relative to the total #{metric3} in the entire program.
|
|
127
|
-
total - The total #{metric2} by this method and its children.
|
|
128
|
-
self - The #{metric2} by this method.
|
|
129
|
-
wait - The time this method spent waiting for other threads.
|
|
130
|
-
child - The #{metric2} by this method's children.
|
|
131
|
-
calls - The number of times this method was called.
|
|
132
|
-
name - The name of the method.
|
|
133
|
-
location - The location of the method.
|
|
134
|
-
|
|
135
|
-
The interpretation of method names is:
|
|
136
|
-
|
|
137
|
-
* MyObject#test - An instance method "test" of the class "MyObject"
|
|
138
|
-
* <Object:MyObject>#test - The <> characters indicate a method on a singleton class.
|
|
139
|
-
|
|
140
|
-
EOT
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
end
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module RubyProf
|
|
4
|
+
# This is the base class for all Printers. It is never used directly.
|
|
5
|
+
class AbstractPrinter
|
|
6
|
+
# :stopdoc:
|
|
7
|
+
def self.needs_dir?
|
|
8
|
+
false
|
|
9
|
+
end
|
|
10
|
+
# :startdoc:
|
|
11
|
+
|
|
12
|
+
# Create a new printer.
|
|
13
|
+
#
|
|
14
|
+
# result should be the output generated from a profiling run
|
|
15
|
+
def initialize(result)
|
|
16
|
+
@result = result
|
|
17
|
+
@output = nil
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
attr_reader :min_percent, :max_percent, :filter_by, :sort_method
|
|
21
|
+
|
|
22
|
+
# Returns the time format used to show when a profile was run
|
|
23
|
+
def time_format
|
|
24
|
+
'%A, %B %-d at %l:%M:%S %p (%Z)'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Prints a report to the provided output.
|
|
28
|
+
#
|
|
29
|
+
# output - Any IO object, including STDOUT or a file.
|
|
30
|
+
# The default value is STDOUT.
|
|
31
|
+
#
|
|
32
|
+
# Keyword arguments:
|
|
33
|
+
# min_percent - Number 0 to 100 that specifies the minimum
|
|
34
|
+
# %self (the methods self time divided by the
|
|
35
|
+
# overall total time) that a method must take
|
|
36
|
+
# for it to be printed out in the report.
|
|
37
|
+
# Default value is 0.
|
|
38
|
+
#
|
|
39
|
+
# max_percent - Number 0 to 100 that specifies the maximum
|
|
40
|
+
# %self for methods to include.
|
|
41
|
+
# Default value is 100.
|
|
42
|
+
#
|
|
43
|
+
# filter_by - Which time metric to use when applying
|
|
44
|
+
# min_percent and max_percent filters.
|
|
45
|
+
# Default value is :self_time.
|
|
46
|
+
#
|
|
47
|
+
# sort_method - Specifies method used for sorting method infos.
|
|
48
|
+
# Available values are :total_time, :self_time,
|
|
49
|
+
# :wait_time, :children_time.
|
|
50
|
+
# Default value depends on the printer.
|
|
51
|
+
def print(output = STDOUT, min_percent: 0, max_percent: 100, filter_by: :self_time, sort_method: nil, max_depth: nil, **)
|
|
52
|
+
@output = output
|
|
53
|
+
@min_percent = min_percent
|
|
54
|
+
@max_percent = max_percent
|
|
55
|
+
@filter_by = filter_by
|
|
56
|
+
@sort_method = sort_method || :total_time
|
|
57
|
+
@max_depth = max_depth
|
|
58
|
+
print_threads
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def method_location(method)
|
|
62
|
+
if method.source_file
|
|
63
|
+
"#{method.source_file}:#{method.line}"
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def method_href(thread, method)
|
|
68
|
+
h(method.full_name.gsub(/[><#\.\?=:]/,"_") + "_" + thread.fiber_id.to_s)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def open_asset(file)
|
|
72
|
+
path = File.join(File.expand_path('../../assets', __FILE__), file)
|
|
73
|
+
File.open(path, 'rb').read
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def print_threads
|
|
77
|
+
@result.threads.each do |thread|
|
|
78
|
+
print_thread(thread)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def print_thread(thread)
|
|
83
|
+
print_header(thread)
|
|
84
|
+
print_methods(thread)
|
|
85
|
+
print_footer(thread)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def print_header(thread)
|
|
89
|
+
@output << "Measure Mode: %s\n" % @result.measure_mode_string
|
|
90
|
+
@output << "Thread ID: %d\n" % thread.id
|
|
91
|
+
@output << "Fiber ID: %d\n" % thread.fiber_id unless thread.id == thread.fiber_id
|
|
92
|
+
@output << "Total: %0.6f\n" % thread.total_time
|
|
93
|
+
@output << "Sort by: #{sort_method}\n"
|
|
94
|
+
@output << "\n"
|
|
95
|
+
print_column_headers
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def print_column_headers
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def print_footer(thread)
|
|
102
|
+
metric_data = {
|
|
103
|
+
0 => { label: "time", prefix: "", suffix: "spent" },
|
|
104
|
+
1 => { label: "time", prefix: "", suffix: "spent" },
|
|
105
|
+
2 => { label: "allocations", prefix: "number of ", suffix: "made" },
|
|
106
|
+
3 => { label: "memory", prefix: "", suffix: "used" }
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
metric = metric_data[@result.measure_mode]
|
|
110
|
+
|
|
111
|
+
metric_label = metric[:label]
|
|
112
|
+
metric_suffix = metric[:suffix]
|
|
113
|
+
metric_prefix = metric[:prefix]
|
|
114
|
+
|
|
115
|
+
metric1 = "#{metric_label} #{metric_suffix}"
|
|
116
|
+
metric2 = "#{metric_prefix}#{metric1}"
|
|
117
|
+
metric3 = metric_label
|
|
118
|
+
|
|
119
|
+
# Output the formatted text
|
|
120
|
+
@output << <<~EOT
|
|
121
|
+
|
|
122
|
+
* recursively called methods
|
|
123
|
+
|
|
124
|
+
Columns are:
|
|
125
|
+
|
|
126
|
+
%self - The percentage of #{metric1} by this method relative to the total #{metric3} in the entire program.
|
|
127
|
+
total - The total #{metric2} by this method and its children.
|
|
128
|
+
self - The #{metric2} by this method.
|
|
129
|
+
wait - The time this method spent waiting for other threads.
|
|
130
|
+
child - The #{metric2} by this method's children.
|
|
131
|
+
calls - The number of times this method was called.
|
|
132
|
+
name - The name of the method.
|
|
133
|
+
location - The location of the method.
|
|
134
|
+
|
|
135
|
+
The interpretation of method names is:
|
|
136
|
+
|
|
137
|
+
* MyObject#test - An instance method "test" of the class "MyObject"
|
|
138
|
+
* <Object:MyObject>#test - The <> characters indicate a method on a singleton class.
|
|
139
|
+
|
|
140
|
+
EOT
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
@@ -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
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
module RubyProf
|
|
2
|
-
VERSION = "2.0.
|
|
3
|
-
end
|
|
1
|
+
module RubyProf
|
|
2
|
+
VERSION = "2.0.5"
|
|
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
|
+
version: 2.0.5
|
|
5
5
|
platform: ruby
|
|
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
|
|
@@ -97,38 +97,8 @@ files:
|
|
|
97
97
|
- CHANGELOG.md
|
|
98
98
|
- LICENSE
|
|
99
99
|
- README.md
|
|
100
|
-
- Rakefile
|
|
101
100
|
- bin/ruby-prof
|
|
102
101
|
- bin/ruby-prof-check-trace
|
|
103
|
-
- docs/advanced-usage.md
|
|
104
|
-
- docs/alternatives.md
|
|
105
|
-
- docs/architecture.md
|
|
106
|
-
- docs/best-practices.md
|
|
107
|
-
- docs/getting-started.md
|
|
108
|
-
- docs/history.md
|
|
109
|
-
- docs/index.md
|
|
110
|
-
- docs/profiling-rails.md
|
|
111
|
-
- docs/public/examples/example.rb
|
|
112
|
-
- docs/public/examples/generate_reports.rb
|
|
113
|
-
- docs/public/examples/reports/call_info.txt
|
|
114
|
-
- docs/public/examples/reports/call_stack.html
|
|
115
|
-
- docs/public/examples/reports/callgrind.out
|
|
116
|
-
- docs/public/examples/reports/flame_graph.html
|
|
117
|
-
- docs/public/examples/reports/flat.txt
|
|
118
|
-
- docs/public/examples/reports/graph.dot
|
|
119
|
-
- docs/public/examples/reports/graph.html
|
|
120
|
-
- docs/public/examples/reports/graph.txt
|
|
121
|
-
- docs/public/examples/reports/graphviz_viewer.html
|
|
122
|
-
- docs/public/images/call_stack.png
|
|
123
|
-
- docs/public/images/class_diagram.png
|
|
124
|
-
- docs/public/images/dot_printer.png
|
|
125
|
-
- docs/public/images/flame_graph.png
|
|
126
|
-
- docs/public/images/flat.png
|
|
127
|
-
- docs/public/images/graph.png
|
|
128
|
-
- docs/public/images/graph_html.png
|
|
129
|
-
- docs/public/images/ruby-prof-logo.svg
|
|
130
|
-
- docs/reports.md
|
|
131
|
-
- docs/stylesheets/extra.css
|
|
132
102
|
- ext/ruby_prof/extconf.rb
|
|
133
103
|
- ext/ruby_prof/rp_allocation.c
|
|
134
104
|
- ext/ruby_prof/rp_allocation.h
|
|
@@ -179,56 +149,6 @@ files:
|
|
|
179
149
|
- lib/ruby-prof/thread.rb
|
|
180
150
|
- lib/ruby-prof/version.rb
|
|
181
151
|
- lib/unprof.rb
|
|
182
|
-
- ruby-prof.gemspec
|
|
183
|
-
- test/abstract_printer_test.rb
|
|
184
|
-
- test/alias_test.rb
|
|
185
|
-
- test/call_tree_builder.rb
|
|
186
|
-
- test/call_tree_test.rb
|
|
187
|
-
- test/call_tree_visitor_test.rb
|
|
188
|
-
- test/call_trees_test.rb
|
|
189
|
-
- test/duplicate_names_test.rb
|
|
190
|
-
- test/dynamic_method_test.rb
|
|
191
|
-
- test/enumerable_test.rb
|
|
192
|
-
- test/exceptions_test.rb
|
|
193
|
-
- test/exclude_methods_test.rb
|
|
194
|
-
- test/exclude_threads_test.rb
|
|
195
|
-
- test/fiber_test.rb
|
|
196
|
-
- test/gc_test.rb
|
|
197
|
-
- test/inverse_call_tree_test.rb
|
|
198
|
-
- test/line_number_test.rb
|
|
199
|
-
- test/marshal_test.rb
|
|
200
|
-
- test/measure_allocations.rb
|
|
201
|
-
- test/measure_allocations_test.rb
|
|
202
|
-
- test/measure_process_time_test.rb
|
|
203
|
-
- test/measure_times.rb
|
|
204
|
-
- test/measure_wall_time_test.rb
|
|
205
|
-
- test/measurement_test.rb
|
|
206
|
-
- test/merge_test.rb
|
|
207
|
-
- test/method_info_test.rb
|
|
208
|
-
- test/multi_printer_test.rb
|
|
209
|
-
- test/no_method_class_test.rb
|
|
210
|
-
- test/pause_resume_test.rb
|
|
211
|
-
- test/prime.rb
|
|
212
|
-
- test/prime_script.rb
|
|
213
|
-
- test/printer_call_stack_test.rb
|
|
214
|
-
- test/printer_call_tree_test.rb
|
|
215
|
-
- test/printer_flame_graph_test.rb
|
|
216
|
-
- test/printer_flat_test.rb
|
|
217
|
-
- test/printer_graph_html_test.rb
|
|
218
|
-
- test/printer_graph_test.rb
|
|
219
|
-
- test/printers_test.rb
|
|
220
|
-
- test/printing_recursive_graph_test.rb
|
|
221
|
-
- test/profile_test.rb
|
|
222
|
-
- test/rack_test.rb
|
|
223
|
-
- test/recursive_test.rb
|
|
224
|
-
- test/scheduler.rb
|
|
225
|
-
- test/singleton_test.rb
|
|
226
|
-
- test/stack_printer_test.rb
|
|
227
|
-
- test/start_stop_test.rb
|
|
228
|
-
- test/test_helper.rb
|
|
229
|
-
- test/thread_test.rb
|
|
230
|
-
- test/unique_call_path_test.rb
|
|
231
|
-
- test/yarv_test.rb
|
|
232
152
|
homepage: https://github.com/ruby-prof/ruby-prof
|
|
233
153
|
licenses:
|
|
234
154
|
- BSD-2-Clause
|
|
@@ -236,7 +156,7 @@ metadata:
|
|
|
236
156
|
bug_tracker_uri: https://github.com/ruby-prof/ruby-prof/issues
|
|
237
157
|
changelog_uri: https://github.com/ruby-prof/ruby-prof/blob/master/CHANGELOG.md
|
|
238
158
|
documentation_uri: https://ruby-prof.github.io/
|
|
239
|
-
source_code_uri: https://github.com/ruby-prof/ruby-prof/tree/
|
|
159
|
+
source_code_uri: https://github.com/ruby-prof/ruby-prof/tree/2.0.5
|
|
240
160
|
rdoc_options: []
|
|
241
161
|
require_paths:
|
|
242
162
|
- lib
|
|
@@ -254,5 +174,4 @@ requirements: []
|
|
|
254
174
|
rubygems_version: 4.0.6
|
|
255
175
|
specification_version: 4
|
|
256
176
|
summary: Fast Ruby profiler
|
|
257
|
-
test_files:
|
|
258
|
-
- 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
|