ruby-prof 1.7.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/{CHANGES → CHANGELOG.md} +112 -178
- data/README.md +5 -5
- data/bin/ruby-prof +1 -4
- data/docs/advanced-usage.md +132 -0
- data/docs/alternatives.md +98 -0
- data/docs/architecture.md +122 -0
- data/docs/best-practices.md +27 -0
- data/docs/getting-started.md +130 -0
- data/docs/history.md +11 -0
- data/docs/index.md +45 -0
- data/docs/profiling-rails.md +64 -0
- data/docs/public/examples/example.rb +33 -0
- data/docs/public/examples/generate_reports.rb +92 -0
- data/docs/public/examples/reports/call_info.txt +27 -0
- data/docs/public/examples/reports/call_stack.html +835 -0
- data/docs/public/examples/reports/callgrind.out +150 -0
- data/docs/public/examples/reports/flame_graph.html +408 -0
- data/docs/public/examples/reports/flat.txt +45 -0
- data/docs/public/examples/reports/graph.dot +129 -0
- data/docs/public/examples/reports/graph.html +1319 -0
- data/docs/public/examples/reports/graph.txt +100 -0
- data/docs/public/examples/reports/graphviz_viewer.html +1 -0
- 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 +1 -0
- data/docs/reports.md +150 -0
- data/docs/stylesheets/extra.css +80 -0
- data/ext/ruby_prof/rp_allocation.c +0 -15
- data/ext/ruby_prof/rp_allocation.h +29 -33
- data/ext/ruby_prof/rp_call_tree.c +3 -0
- data/ext/ruby_prof/rp_call_tree.h +1 -4
- data/ext/ruby_prof/rp_call_trees.h +1 -4
- data/ext/ruby_prof/rp_measurement.c +0 -5
- data/ext/ruby_prof/rp_measurement.h +49 -53
- data/ext/ruby_prof/rp_method.c +3 -0
- data/ext/ruby_prof/rp_method.h +1 -4
- data/ext/ruby_prof/rp_profile.c +1 -1
- data/ext/ruby_prof/rp_profile.h +1 -5
- data/ext/ruby_prof/rp_stack.h +50 -53
- data/ext/ruby_prof/rp_thread.h +1 -4
- data/ext/ruby_prof/ruby_prof.h +1 -4
- data/ext/ruby_prof/vc/ruby_prof.vcxproj +7 -8
- data/lib/ruby-prof/assets/call_stack_printer.html.erb +746 -711
- data/lib/ruby-prof/assets/flame_graph_printer.html.erb +412 -0
- data/lib/ruby-prof/assets/graph_printer.html.erb +355 -355
- data/lib/ruby-prof/call_tree.rb +57 -57
- data/lib/ruby-prof/call_tree_visitor.rb +36 -36
- data/lib/ruby-prof/measurement.rb +17 -17
- data/lib/ruby-prof/printers/abstract_printer.rb +19 -33
- data/lib/ruby-prof/printers/call_info_printer.rb +53 -53
- data/lib/ruby-prof/printers/call_stack_printer.rb +168 -180
- data/lib/ruby-prof/printers/call_tree_printer.rb +132 -145
- data/lib/ruby-prof/printers/dot_printer.rb +177 -132
- data/lib/ruby-prof/printers/flame_graph_printer.rb +79 -0
- data/lib/ruby-prof/printers/flat_printer.rb +52 -52
- data/lib/ruby-prof/printers/graph_html_printer.rb +62 -63
- data/lib/ruby-prof/printers/graph_printer.rb +112 -113
- data/lib/ruby-prof/printers/multi_printer.rb +134 -127
- data/lib/ruby-prof/profile.rb +13 -0
- data/lib/ruby-prof/rack.rb +114 -105
- data/lib/ruby-prof/task.rb +147 -147
- data/lib/ruby-prof/thread.rb +20 -20
- data/lib/ruby-prof/version.rb +1 -1
- data/lib/ruby-prof.rb +50 -52
- data/lib/unprof.rb +10 -10
- data/ruby-prof.gemspec +5 -5
- data/test/abstract_printer_test.rb +25 -27
- data/test/alias_test.rb +203 -117
- data/test/call_tree_builder.rb +126 -126
- data/test/call_tree_visitor_test.rb +27 -27
- data/test/call_trees_test.rb +66 -66
- data/test/duplicate_names_test.rb +32 -32
- data/test/dynamic_method_test.rb +50 -50
- data/test/exceptions_test.rb +24 -24
- data/test/exclude_threads_test.rb +48 -48
- data/test/fiber_test.rb +72 -72
- data/test/inverse_call_tree_test.rb +174 -174
- data/test/line_number_test.rb +138 -1
- data/test/marshal_test.rb +144 -145
- data/test/measure_allocations.rb +26 -26
- data/test/measure_allocations_test.rb +340 -1
- data/test/measure_process_time_test.rb +3098 -3142
- data/test/measure_times.rb +56 -56
- data/test/measure_wall_time_test.rb +511 -372
- data/test/measurement_test.rb +82 -82
- data/test/merge_test.rb +48 -48
- data/test/multi_printer_test.rb +52 -66
- data/test/no_method_class_test.rb +15 -15
- data/test/pause_resume_test.rb +171 -171
- data/test/prime.rb +54 -54
- data/test/prime_script.rb +5 -5
- data/test/printer_call_stack_test.rb +28 -27
- data/test/printer_call_tree_test.rb +30 -30
- data/test/printer_flame_graph_test.rb +82 -0
- data/test/printer_flat_test.rb +99 -99
- data/test/printer_graph_html_test.rb +62 -59
- data/test/printer_graph_test.rb +42 -40
- data/test/printers_test.rb +28 -44
- data/test/printing_recursive_graph_test.rb +81 -81
- data/test/profile_test.rb +101 -101
- data/test/rack_test.rb +103 -93
- data/test/recursive_test.rb +139 -139
- data/test/scheduler.rb +4 -0
- data/test/singleton_test.rb +39 -38
- data/test/stack_printer_test.rb +61 -61
- data/test/start_stop_test.rb +106 -106
- data/test/test_helper.rb +4 -0
- data/test/thread_test.rb +29 -29
- data/test/unique_call_path_test.rb +123 -123
- data/test/yarv_test.rb +56 -56
- metadata +53 -11
- data/ext/ruby_prof/rp_measure_memory.c +0 -46
- data/lib/ruby-prof/compatibility.rb +0 -113
- data/test/compatibility_test.rb +0 -49
- data/test/measure_memory_test.rb +0 -1193
|
@@ -1,123 +1,123 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# encoding: UTF-8
|
|
3
|
-
|
|
4
|
-
require File.expand_path('../test_helper', __FILE__)
|
|
5
|
-
|
|
6
|
-
class UniqueCallPath
|
|
7
|
-
def method_a(i)
|
|
8
|
-
if i==1
|
|
9
|
-
method_b
|
|
10
|
-
else
|
|
11
|
-
method_c
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def method_b
|
|
16
|
-
method_c
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def method_c
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def method_k(i)
|
|
23
|
-
method_a(i)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
# -- Tests ----
|
|
29
|
-
class UniqueCallPathTest < TestCase
|
|
30
|
-
def test_root
|
|
31
|
-
unique_call_path = UniqueCallPath.new
|
|
32
|
-
|
|
33
|
-
result = RubyProf::Profile.profile do
|
|
34
|
-
unique_call_path.method_a(1)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
root_call_info = result.threads.first.call_tree
|
|
38
|
-
assert_equal("UniqueCallPathTest#test_root", root_call_info.target.full_name)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def test_root_children
|
|
42
|
-
unique_call_path = UniqueCallPath.new
|
|
43
|
-
|
|
44
|
-
result = RubyProf::Profile.profile do
|
|
45
|
-
unique_call_path.method_a(1)
|
|
46
|
-
unique_call_path.method_k(2)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
root_call_info = result.threads.first.call_tree
|
|
50
|
-
children = root_call_info.children.sort do |c1, c2|
|
|
51
|
-
c1.target.full_name <=> c2.target.full_name
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
assert_equal(2, children.length)
|
|
55
|
-
assert_equal("UniqueCallPath#method_a", children[0].target.full_name)
|
|
56
|
-
assert_equal("UniqueCallPath#method_k", children[1].target.full_name)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def test_children_of
|
|
60
|
-
unique_call_path = UniqueCallPath.new
|
|
61
|
-
|
|
62
|
-
result = RubyProf::Profile.profile do
|
|
63
|
-
unique_call_path.method_a(1)
|
|
64
|
-
unique_call_path.method_k(2)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
root_call_info = result.threads.first.call_tree
|
|
68
|
-
assert_equal("UniqueCallPathTest#test_children_of", root_call_info.target.full_name)
|
|
69
|
-
|
|
70
|
-
call_info_a = root_call_info.children.detect do |call_tree|
|
|
71
|
-
call_tree.target.full_name == "UniqueCallPath#method_a"
|
|
72
|
-
end
|
|
73
|
-
refute_nil(call_info_a)
|
|
74
|
-
|
|
75
|
-
_children_of_a = call_info_a.children.inject(Array.new) do |array, c|
|
|
76
|
-
if c.parent.eql?(call_info_a)
|
|
77
|
-
array << c
|
|
78
|
-
end
|
|
79
|
-
array
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
assert_equal(2, call_info_a.children.length)
|
|
83
|
-
assert_equal("Integer#==", call_info_a.children[0].target.full_name)
|
|
84
|
-
assert_equal("UniqueCallPath#method_b", call_info_a.children[1].target.full_name)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def test_unique_path
|
|
88
|
-
unique_call_path = UniqueCallPath.new
|
|
89
|
-
|
|
90
|
-
result = RubyProf::Profile.profile do
|
|
91
|
-
unique_call_path.method_a(1)
|
|
92
|
-
unique_call_path.method_k(1)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
root_call_info = result.threads.first.call_tree
|
|
96
|
-
assert_equal("UniqueCallPathTest#test_unique_path", root_call_info.target.full_name)
|
|
97
|
-
|
|
98
|
-
call_info_a = root_call_info.children.detect do |call_tree|
|
|
99
|
-
call_tree.target.full_name == "UniqueCallPath#method_a"
|
|
100
|
-
end
|
|
101
|
-
refute_nil(call_info_a)
|
|
102
|
-
|
|
103
|
-
children_of_a = call_info_a.children.reduce(Array.new) do |array, c|
|
|
104
|
-
if c.parent.eql?(call_info_a)
|
|
105
|
-
array << c
|
|
106
|
-
end
|
|
107
|
-
array
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
children_of_a = children_of_a.sort do |c1, c2|
|
|
111
|
-
c1.target.full_name <=> c2.target.full_name
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
assert_equal(2, call_info_a.children.length)
|
|
115
|
-
assert_equal(2, children_of_a.length)
|
|
116
|
-
|
|
117
|
-
assert_equal(1, children_of_a[0].called)
|
|
118
|
-
assert_equal("Integer#==", children_of_a[0].target.full_name)
|
|
119
|
-
|
|
120
|
-
assert_equal(1, children_of_a[1].called)
|
|
121
|
-
assert_equal("UniqueCallPath#method_b", children_of_a[1].target.full_name)
|
|
122
|
-
end
|
|
123
|
-
end
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
|
|
4
|
+
require File.expand_path('../test_helper', __FILE__)
|
|
5
|
+
|
|
6
|
+
class UniqueCallPath
|
|
7
|
+
def method_a(i)
|
|
8
|
+
if i==1
|
|
9
|
+
method_b
|
|
10
|
+
else
|
|
11
|
+
method_c
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def method_b
|
|
16
|
+
method_c
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def method_c
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def method_k(i)
|
|
23
|
+
method_a(i)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# -- Tests ----
|
|
29
|
+
class UniqueCallPathTest < TestCase
|
|
30
|
+
def test_root
|
|
31
|
+
unique_call_path = UniqueCallPath.new
|
|
32
|
+
|
|
33
|
+
result = RubyProf::Profile.profile do
|
|
34
|
+
unique_call_path.method_a(1)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
root_call_info = result.threads.first.call_tree
|
|
38
|
+
assert_equal("UniqueCallPathTest#test_root", root_call_info.target.full_name)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def test_root_children
|
|
42
|
+
unique_call_path = UniqueCallPath.new
|
|
43
|
+
|
|
44
|
+
result = RubyProf::Profile.profile do
|
|
45
|
+
unique_call_path.method_a(1)
|
|
46
|
+
unique_call_path.method_k(2)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
root_call_info = result.threads.first.call_tree
|
|
50
|
+
children = root_call_info.children.sort do |c1, c2|
|
|
51
|
+
c1.target.full_name <=> c2.target.full_name
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
assert_equal(2, children.length)
|
|
55
|
+
assert_equal("UniqueCallPath#method_a", children[0].target.full_name)
|
|
56
|
+
assert_equal("UniqueCallPath#method_k", children[1].target.full_name)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def test_children_of
|
|
60
|
+
unique_call_path = UniqueCallPath.new
|
|
61
|
+
|
|
62
|
+
result = RubyProf::Profile.profile do
|
|
63
|
+
unique_call_path.method_a(1)
|
|
64
|
+
unique_call_path.method_k(2)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
root_call_info = result.threads.first.call_tree
|
|
68
|
+
assert_equal("UniqueCallPathTest#test_children_of", root_call_info.target.full_name)
|
|
69
|
+
|
|
70
|
+
call_info_a = root_call_info.children.detect do |call_tree|
|
|
71
|
+
call_tree.target.full_name == "UniqueCallPath#method_a"
|
|
72
|
+
end
|
|
73
|
+
refute_nil(call_info_a)
|
|
74
|
+
|
|
75
|
+
_children_of_a = call_info_a.children.inject(Array.new) do |array, c|
|
|
76
|
+
if c.parent.eql?(call_info_a)
|
|
77
|
+
array << c
|
|
78
|
+
end
|
|
79
|
+
array
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
assert_equal(2, call_info_a.children.length)
|
|
83
|
+
assert_equal("Integer#==", call_info_a.children[0].target.full_name)
|
|
84
|
+
assert_equal("UniqueCallPath#method_b", call_info_a.children[1].target.full_name)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def test_unique_path
|
|
88
|
+
unique_call_path = UniqueCallPath.new
|
|
89
|
+
|
|
90
|
+
result = RubyProf::Profile.profile do
|
|
91
|
+
unique_call_path.method_a(1)
|
|
92
|
+
unique_call_path.method_k(1)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
root_call_info = result.threads.first.call_tree
|
|
96
|
+
assert_equal("UniqueCallPathTest#test_unique_path", root_call_info.target.full_name)
|
|
97
|
+
|
|
98
|
+
call_info_a = root_call_info.children.detect do |call_tree|
|
|
99
|
+
call_tree.target.full_name == "UniqueCallPath#method_a"
|
|
100
|
+
end
|
|
101
|
+
refute_nil(call_info_a)
|
|
102
|
+
|
|
103
|
+
children_of_a = call_info_a.children.reduce(Array.new) do |array, c|
|
|
104
|
+
if c.parent.eql?(call_info_a)
|
|
105
|
+
array << c
|
|
106
|
+
end
|
|
107
|
+
array
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
children_of_a = children_of_a.sort do |c1, c2|
|
|
111
|
+
c1.target.full_name <=> c2.target.full_name
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
assert_equal(2, call_info_a.children.length)
|
|
115
|
+
assert_equal(2, children_of_a.length)
|
|
116
|
+
|
|
117
|
+
assert_equal(1, children_of_a[0].called)
|
|
118
|
+
assert_equal("Integer#==", children_of_a[0].target.full_name)
|
|
119
|
+
|
|
120
|
+
assert_equal(1, children_of_a[1].called)
|
|
121
|
+
assert_equal("UniqueCallPath#method_b", children_of_a[1].target.full_name)
|
|
122
|
+
end
|
|
123
|
+
end
|
data/test/yarv_test.rb
CHANGED
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# encoding: UTF-8
|
|
3
|
-
|
|
4
|
-
require File.expand_path('../test_helper', __FILE__)
|
|
5
|
-
|
|
6
|
-
# tests for bugs reported by users
|
|
7
|
-
class YarvTest < TestCase
|
|
8
|
-
def setup
|
|
9
|
-
super
|
|
10
|
-
define_methods
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def test_array_push_unoptimized
|
|
14
|
-
a = nil
|
|
15
|
-
result = RubyProf::Profile.profile(measure_mode: RubyProf::WALL_TIME) do
|
|
16
|
-
a = self.array_push_unoptimized
|
|
17
|
-
end
|
|
18
|
-
assert_equal 2, a.length
|
|
19
|
-
assert_equal ["YarvTest#test_array_push_unoptimized", "YarvTest#array_push_unoptimized", 'Array#<<', "Array#push"], result.threads.first.methods.map(&:full_name)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def test_array_push_optimized
|
|
23
|
-
a = nil
|
|
24
|
-
result = RubyProf::Profile.profile(measure_mode: RubyProf::WALL_TIME) do
|
|
25
|
-
a = self.array_push_optimized
|
|
26
|
-
end
|
|
27
|
-
assert_equal(2, a.length)
|
|
28
|
-
assert_equal(["YarvTest#test_array_push_optimized", "YarvTest#array_push_optimized", "Array#<<", "Array#push"], result.threads.first.methods.map(&:full_name))
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
private
|
|
32
|
-
|
|
33
|
-
def define_methods
|
|
34
|
-
return if respond_to?(:array_push_optimized)
|
|
35
|
-
old_compile_option = RubyVM::InstructionSequence.compile_option
|
|
36
|
-
RubyVM::InstructionSequence.compile_option = {
|
|
37
|
-
:
|
|
38
|
-
:
|
|
39
|
-
}
|
|
40
|
-
self.class.class_eval <<-"EOM"
|
|
41
|
-
def array_push_unoptimized
|
|
42
|
-
a = []
|
|
43
|
-
a << 1
|
|
44
|
-
a.push 2
|
|
45
|
-
end
|
|
46
|
-
EOM
|
|
47
|
-
RubyVM::InstructionSequence.compile_option = old_compile_option
|
|
48
|
-
self.class.class_eval <<-"EOM"
|
|
49
|
-
def array_push_optimized
|
|
50
|
-
a = []
|
|
51
|
-
a << 1
|
|
52
|
-
a.push 2
|
|
53
|
-
end
|
|
54
|
-
EOM
|
|
55
|
-
end
|
|
56
|
-
end
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
|
|
4
|
+
require File.expand_path('../test_helper', __FILE__)
|
|
5
|
+
|
|
6
|
+
# tests for bugs reported by users
|
|
7
|
+
class YarvTest < TestCase
|
|
8
|
+
def setup
|
|
9
|
+
super
|
|
10
|
+
define_methods
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def test_array_push_unoptimized
|
|
14
|
+
a = nil
|
|
15
|
+
result = RubyProf::Profile.profile(measure_mode: RubyProf::WALL_TIME) do
|
|
16
|
+
a = self.array_push_unoptimized
|
|
17
|
+
end
|
|
18
|
+
assert_equal 2, a.length
|
|
19
|
+
assert_equal ["YarvTest#test_array_push_unoptimized", "YarvTest#array_push_unoptimized", 'Array#<<', "Array#push"], result.threads.first.methods.map(&:full_name)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_array_push_optimized
|
|
23
|
+
a = nil
|
|
24
|
+
result = RubyProf::Profile.profile(measure_mode: RubyProf::WALL_TIME) do
|
|
25
|
+
a = self.array_push_optimized
|
|
26
|
+
end
|
|
27
|
+
assert_equal(2, a.length)
|
|
28
|
+
assert_equal(["YarvTest#test_array_push_optimized", "YarvTest#array_push_optimized", "Array#<<", "Array#push"], result.threads.first.methods.map(&:full_name))
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def define_methods
|
|
34
|
+
return if respond_to?(:array_push_optimized)
|
|
35
|
+
old_compile_option = RubyVM::InstructionSequence.compile_option
|
|
36
|
+
RubyVM::InstructionSequence.compile_option = {
|
|
37
|
+
trace_instruction: true,
|
|
38
|
+
specialized_instruction: false
|
|
39
|
+
}
|
|
40
|
+
self.class.class_eval <<-"EOM"
|
|
41
|
+
def array_push_unoptimized
|
|
42
|
+
a = []
|
|
43
|
+
a << 1
|
|
44
|
+
a.push 2
|
|
45
|
+
end
|
|
46
|
+
EOM
|
|
47
|
+
RubyVM::InstructionSequence.compile_option = old_compile_option
|
|
48
|
+
self.class.class_eval <<-"EOM"
|
|
49
|
+
def array_push_optimized
|
|
50
|
+
a = []
|
|
51
|
+
a << 1
|
|
52
|
+
a.push 2
|
|
53
|
+
end
|
|
54
|
+
EOM
|
|
55
|
+
end
|
|
56
|
+
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:
|
|
4
|
+
version: 2.0.0
|
|
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:
|
|
10
|
+
date: 2026-02-13 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: base64
|
|
@@ -23,6 +23,20 @@ dependencies:
|
|
|
23
23
|
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: ostruct
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0'
|
|
26
40
|
- !ruby/object:Gem::Dependency
|
|
27
41
|
name: minitest
|
|
28
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -80,12 +94,41 @@ extensions:
|
|
|
80
94
|
- ext/ruby_prof/extconf.rb
|
|
81
95
|
extra_rdoc_files: []
|
|
82
96
|
files:
|
|
83
|
-
-
|
|
97
|
+
- CHANGELOG.md
|
|
84
98
|
- LICENSE
|
|
85
99
|
- README.md
|
|
86
100
|
- Rakefile
|
|
87
101
|
- bin/ruby-prof
|
|
88
102
|
- 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
|
|
89
132
|
- ext/ruby_prof/extconf.rb
|
|
90
133
|
- ext/ruby_prof/rp_allocation.c
|
|
91
134
|
- ext/ruby_prof/rp_allocation.h
|
|
@@ -94,7 +137,6 @@ files:
|
|
|
94
137
|
- ext/ruby_prof/rp_call_trees.c
|
|
95
138
|
- ext/ruby_prof/rp_call_trees.h
|
|
96
139
|
- ext/ruby_prof/rp_measure_allocations.c
|
|
97
|
-
- ext/ruby_prof/rp_measure_memory.c
|
|
98
140
|
- ext/ruby_prof/rp_measure_process_time.c
|
|
99
141
|
- ext/ruby_prof/rp_measure_wall_time.c
|
|
100
142
|
- ext/ruby_prof/rp_measurement.c
|
|
@@ -114,10 +156,10 @@ files:
|
|
|
114
156
|
- lib/ruby-prof.rb
|
|
115
157
|
- lib/ruby-prof/assets/call_stack_printer.html.erb
|
|
116
158
|
- lib/ruby-prof/assets/call_stack_printer.png
|
|
159
|
+
- lib/ruby-prof/assets/flame_graph_printer.html.erb
|
|
117
160
|
- lib/ruby-prof/assets/graph_printer.html.erb
|
|
118
161
|
- lib/ruby-prof/call_tree.rb
|
|
119
162
|
- lib/ruby-prof/call_tree_visitor.rb
|
|
120
|
-
- lib/ruby-prof/compatibility.rb
|
|
121
163
|
- lib/ruby-prof/exclude_common_methods.rb
|
|
122
164
|
- lib/ruby-prof/measurement.rb
|
|
123
165
|
- lib/ruby-prof/method_info.rb
|
|
@@ -126,6 +168,7 @@ files:
|
|
|
126
168
|
- lib/ruby-prof/printers/call_stack_printer.rb
|
|
127
169
|
- lib/ruby-prof/printers/call_tree_printer.rb
|
|
128
170
|
- lib/ruby-prof/printers/dot_printer.rb
|
|
171
|
+
- lib/ruby-prof/printers/flame_graph_printer.rb
|
|
129
172
|
- lib/ruby-prof/printers/flat_printer.rb
|
|
130
173
|
- lib/ruby-prof/printers/graph_html_printer.rb
|
|
131
174
|
- lib/ruby-prof/printers/graph_printer.rb
|
|
@@ -143,7 +186,6 @@ files:
|
|
|
143
186
|
- test/call_tree_test.rb
|
|
144
187
|
- test/call_tree_visitor_test.rb
|
|
145
188
|
- test/call_trees_test.rb
|
|
146
|
-
- test/compatibility_test.rb
|
|
147
189
|
- test/duplicate_names_test.rb
|
|
148
190
|
- test/dynamic_method_test.rb
|
|
149
191
|
- test/enumerable_test.rb
|
|
@@ -157,7 +199,6 @@ files:
|
|
|
157
199
|
- test/marshal_test.rb
|
|
158
200
|
- test/measure_allocations.rb
|
|
159
201
|
- test/measure_allocations_test.rb
|
|
160
|
-
- test/measure_memory_test.rb
|
|
161
202
|
- test/measure_process_time_test.rb
|
|
162
203
|
- test/measure_times.rb
|
|
163
204
|
- test/measure_wall_time_test.rb
|
|
@@ -171,6 +212,7 @@ files:
|
|
|
171
212
|
- test/prime_script.rb
|
|
172
213
|
- test/printer_call_stack_test.rb
|
|
173
214
|
- test/printer_call_tree_test.rb
|
|
215
|
+
- test/printer_flame_graph_test.rb
|
|
174
216
|
- test/printer_flat_test.rb
|
|
175
217
|
- test/printer_graph_html_test.rb
|
|
176
218
|
- test/printer_graph_test.rb
|
|
@@ -192,9 +234,9 @@ licenses:
|
|
|
192
234
|
- BSD-2-Clause
|
|
193
235
|
metadata:
|
|
194
236
|
bug_tracker_uri: https://github.com/ruby-prof/ruby-prof/issues
|
|
195
|
-
changelog_uri: https://github.com/ruby-prof/ruby-prof/blob/master/
|
|
237
|
+
changelog_uri: https://github.com/ruby-prof/ruby-prof/blob/master/CHANGELOG.md
|
|
196
238
|
documentation_uri: https://ruby-prof.github.io/
|
|
197
|
-
source_code_uri: https://github.com/ruby-prof/ruby-prof/tree/
|
|
239
|
+
source_code_uri: https://github.com/ruby-prof/ruby-prof/tree/v2.0.0
|
|
198
240
|
rdoc_options: []
|
|
199
241
|
require_paths:
|
|
200
242
|
- lib
|
|
@@ -202,14 +244,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
202
244
|
requirements:
|
|
203
245
|
- - ">="
|
|
204
246
|
- !ruby/object:Gem::Version
|
|
205
|
-
version: 3.
|
|
247
|
+
version: 3.2.0
|
|
206
248
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
207
249
|
requirements:
|
|
208
250
|
- - ">="
|
|
209
251
|
- !ruby/object:Gem::Version
|
|
210
252
|
version: '0'
|
|
211
253
|
requirements: []
|
|
212
|
-
rubygems_version:
|
|
254
|
+
rubygems_version: 4.0.6
|
|
213
255
|
specification_version: 4
|
|
214
256
|
summary: Fast Ruby profiler
|
|
215
257
|
test_files:
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
|
|
2
|
-
Please see the LICENSE file for copyright and distribution information */
|
|
3
|
-
|
|
4
|
-
/* :nodoc: */
|
|
5
|
-
|
|
6
|
-
#include "rp_measurement.h"
|
|
7
|
-
|
|
8
|
-
static VALUE cMeasureMemory;
|
|
9
|
-
|
|
10
|
-
static double measure_memory(rb_trace_arg_t* trace_arg)
|
|
11
|
-
{
|
|
12
|
-
static double result = 0;
|
|
13
|
-
|
|
14
|
-
if (trace_arg)
|
|
15
|
-
{
|
|
16
|
-
// Only process creation of new objects
|
|
17
|
-
rb_event_flag_t event = rb_tracearg_event_flag(trace_arg);
|
|
18
|
-
if (event == RUBY_INTERNAL_EVENT_NEWOBJ)
|
|
19
|
-
{
|
|
20
|
-
// Don't count allocations of internal IMemo objects
|
|
21
|
-
VALUE object = rb_tracearg_object(trace_arg);
|
|
22
|
-
if (BUILTIN_TYPE(object) != T_IMEMO)
|
|
23
|
-
result += rb_obj_memsize_of(object);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return result;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
prof_measurer_t* prof_measurer_memory(bool track_allocations)
|
|
31
|
-
{
|
|
32
|
-
prof_measurer_t* measure = ALLOC(prof_measurer_t);
|
|
33
|
-
measure->mode = MEASURE_MEMORY;
|
|
34
|
-
measure->measure = measure_memory;
|
|
35
|
-
measure->multiplier = 1;
|
|
36
|
-
// Need to track allocations to get RUBY_INTERNAL_EVENT_NEWOBJ event
|
|
37
|
-
measure->track_allocations = true;
|
|
38
|
-
return measure;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
void rp_init_measure_memory(void)
|
|
42
|
-
{
|
|
43
|
-
rb_define_const(mProf, "MEMORY", INT2NUM(MEASURE_MEMORY));
|
|
44
|
-
|
|
45
|
-
cMeasureMemory = rb_define_class_under(mMeasure, "Allocations", rb_cObject);
|
|
46
|
-
}
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
# These methods are deprecated and are available for backwards compatability.
|
|
4
|
-
module RubyProf
|
|
5
|
-
# call-seq:
|
|
6
|
-
# measure_mode -> measure_mode
|
|
7
|
-
#
|
|
8
|
-
# Returns what ruby-prof is measuring. Valid values include:
|
|
9
|
-
#
|
|
10
|
-
# * RubyProf::WALL_TIME
|
|
11
|
-
# * RubyProf::PROCESS_TIME
|
|
12
|
-
# * RubyProf::ALLOCATIONS
|
|
13
|
-
# * RubyProf::MEMORY
|
|
14
|
-
def self.measure_mode
|
|
15
|
-
@measure_mode ||= RubyProf::WALL_TIME
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# call-seq:
|
|
19
|
-
# measure_mode=value -> void
|
|
20
|
-
#
|
|
21
|
-
# Specifies what ruby-prof should measure. Valid values include:
|
|
22
|
-
#
|
|
23
|
-
# * RubyProf::WALL_TIME - Wall time measures the real-world time elapsed between any two moments. 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 GetTickCount(), on MacOS by mach_absolute_time, on Linux by clock_gettime and otherwise by gettimeofday.
|
|
24
|
-
# * RubyProf::PROCESS_TIME - Process time measures the time used by a process between any two moments. 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.
|
|
25
|
-
# * RubyProf::ALLOCATIONS - Object allocations measures show how many objects each method in a program allocates. Measurements are done via Ruby's GC.stat api.
|
|
26
|
-
# * RubyProf::MEMORY - Memory measures how much memory each method in a program uses. Measurements are done via Ruby's TracePoint api.
|
|
27
|
-
def self.measure_mode=(value)
|
|
28
|
-
@measure_mode = value
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# Returns the threads that ruby-prof should exclude from profiling
|
|
32
|
-
def self.exclude_threads
|
|
33
|
-
@exclude_threads ||= Array.new
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# Specifies which threads ruby-prof should exclude from profiling
|
|
37
|
-
def self.exclude_threads=(value)
|
|
38
|
-
@exclude_threads = value
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# Starts profiling
|
|
42
|
-
def self.start
|
|
43
|
-
ensure_not_running!
|
|
44
|
-
@profile = Profile.new(:measure_mode => measure_mode, :exclude_threads => exclude_threads)
|
|
45
|
-
@profile.start
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# Pauses profiling
|
|
49
|
-
def self.pause
|
|
50
|
-
ensure_running!
|
|
51
|
-
@profile.pause
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# Is a profile running?
|
|
55
|
-
def self.running?
|
|
56
|
-
if defined?(@profile) and @profile
|
|
57
|
-
@profile.running?
|
|
58
|
-
else
|
|
59
|
-
false
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# Resume profiling
|
|
64
|
-
def self.resume
|
|
65
|
-
ensure_running!
|
|
66
|
-
@profile.resume
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
# Stops profiling
|
|
70
|
-
def self.stop
|
|
71
|
-
ensure_running!
|
|
72
|
-
result = @profile.stop
|
|
73
|
-
@profile = nil
|
|
74
|
-
result
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
# Profiles a block
|
|
78
|
-
def self.profile(options = {}, &block)
|
|
79
|
-
ensure_not_running!
|
|
80
|
-
options = {:measure_mode => measure_mode, :exclude_threads => exclude_threads }.merge!(options)
|
|
81
|
-
Profile.profile(options, &block)
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# :nodoc:
|
|
85
|
-
def self.start_script(script)
|
|
86
|
-
start
|
|
87
|
-
load script
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
private
|
|
91
|
-
|
|
92
|
-
def self.ensure_running!
|
|
93
|
-
raise(RuntimeError, "RubyProf.start was not yet called") unless running?
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def self.ensure_not_running!
|
|
97
|
-
raise(RuntimeError, "RubyProf is already running") if running?
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
class << self
|
|
101
|
-
extend Gem::Deprecate
|
|
102
|
-
deprecate :measure_mode, "RubyProf::Profile#measure_mode", 2023, 6
|
|
103
|
-
deprecate :measure_mode=, "RubyProf::Profile.new(measure_mode: ...)", 2023, 6
|
|
104
|
-
deprecate :exclude_threads, "RubyProf::Profile#exclude_threads", 2023, 6
|
|
105
|
-
deprecate :exclude_threads=, "RubyProf::Profile#initialize", 2023, 6
|
|
106
|
-
deprecate :start, "RubyProf::Profile#start", 2023, 6
|
|
107
|
-
deprecate :pause, "RubyProf::Profile#pause", 2023, 6
|
|
108
|
-
deprecate :stop, "RubyProf::Profile#stop", 2023, 6
|
|
109
|
-
deprecate :resume, "RubyProf::Profile#resume", 2023, 6
|
|
110
|
-
deprecate :running?, "RubyProf::Profile#running?", 2023, 6
|
|
111
|
-
deprecate :profile, "RubyProf::Profile.profile", 2023, 6
|
|
112
|
-
end
|
|
113
|
-
end
|