ruby-prof 0.18.0-x64-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGES +500 -0
- data/LICENSE +25 -0
- data/README.rdoc +487 -0
- data/Rakefile +113 -0
- data/bin/ruby-prof +345 -0
- data/bin/ruby-prof-check-trace +45 -0
- data/examples/flat.txt +50 -0
- data/examples/graph.dot +84 -0
- data/examples/graph.html +823 -0
- data/examples/graph.txt +139 -0
- data/examples/multi.flat.txt +23 -0
- data/examples/multi.graph.html +760 -0
- data/examples/multi.grind.dat +114 -0
- data/examples/multi.stack.html +547 -0
- data/examples/stack.html +547 -0
- data/ext/ruby_prof/extconf.rb +68 -0
- data/ext/ruby_prof/rp_call_info.c +425 -0
- data/ext/ruby_prof/rp_call_info.h +53 -0
- data/ext/ruby_prof/rp_measure.c +40 -0
- data/ext/ruby_prof/rp_measure.h +45 -0
- data/ext/ruby_prof/rp_measure_allocations.c +76 -0
- data/ext/ruby_prof/rp_measure_cpu_time.c +136 -0
- data/ext/ruby_prof/rp_measure_gc_runs.c +73 -0
- data/ext/ruby_prof/rp_measure_gc_time.c +60 -0
- data/ext/ruby_prof/rp_measure_memory.c +77 -0
- data/ext/ruby_prof/rp_measure_process_time.c +71 -0
- data/ext/ruby_prof/rp_measure_wall_time.c +45 -0
- data/ext/ruby_prof/rp_method.c +630 -0
- data/ext/ruby_prof/rp_method.h +75 -0
- data/ext/ruby_prof/rp_stack.c +173 -0
- data/ext/ruby_prof/rp_stack.h +63 -0
- data/ext/ruby_prof/rp_thread.c +277 -0
- data/ext/ruby_prof/rp_thread.h +27 -0
- data/ext/ruby_prof/ruby_prof.c +794 -0
- data/ext/ruby_prof/ruby_prof.h +60 -0
- data/ext/ruby_prof/vc/ruby_prof.sln +31 -0
- data/ext/ruby_prof/vc/ruby_prof.vcxproj +141 -0
- data/lib/2.6.3/ruby_prof.so +0 -0
- data/lib/ruby-prof.rb +68 -0
- data/lib/ruby-prof/aggregate_call_info.rb +76 -0
- data/lib/ruby-prof/assets/call_stack_printer.css.html +117 -0
- data/lib/ruby-prof/assets/call_stack_printer.js.html +385 -0
- data/lib/ruby-prof/assets/call_stack_printer.png +0 -0
- data/lib/ruby-prof/call_info.rb +115 -0
- data/lib/ruby-prof/call_info_visitor.rb +40 -0
- data/lib/ruby-prof/compatibility.rb +179 -0
- data/lib/ruby-prof/method_info.rb +121 -0
- data/lib/ruby-prof/printers/abstract_printer.rb +104 -0
- data/lib/ruby-prof/printers/call_info_printer.rb +41 -0
- data/lib/ruby-prof/printers/call_stack_printer.rb +265 -0
- data/lib/ruby-prof/printers/call_tree_printer.rb +143 -0
- data/lib/ruby-prof/printers/dot_printer.rb +132 -0
- data/lib/ruby-prof/printers/flat_printer.rb +70 -0
- data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +83 -0
- data/lib/ruby-prof/printers/graph_html_printer.rb +249 -0
- data/lib/ruby-prof/printers/graph_printer.rb +116 -0
- data/lib/ruby-prof/printers/multi_printer.rb +84 -0
- data/lib/ruby-prof/profile.rb +26 -0
- data/lib/ruby-prof/profile/exclude_common_methods.rb +207 -0
- data/lib/ruby-prof/profile/legacy_method_elimination.rb +50 -0
- data/lib/ruby-prof/rack.rb +174 -0
- data/lib/ruby-prof/task.rb +147 -0
- data/lib/ruby-prof/thread.rb +35 -0
- data/lib/ruby-prof/version.rb +3 -0
- data/lib/unprof.rb +10 -0
- data/ruby-prof.gemspec +58 -0
- data/test/abstract_printer_test.rb +53 -0
- data/test/aggregate_test.rb +136 -0
- data/test/basic_test.rb +128 -0
- data/test/block_test.rb +74 -0
- data/test/call_info_test.rb +78 -0
- data/test/call_info_visitor_test.rb +31 -0
- data/test/duplicate_names_test.rb +32 -0
- data/test/dynamic_method_test.rb +55 -0
- data/test/enumerable_test.rb +21 -0
- data/test/exceptions_test.rb +24 -0
- data/test/exclude_methods_test.rb +146 -0
- data/test/exclude_threads_test.rb +53 -0
- data/test/fiber_test.rb +79 -0
- data/test/issue137_test.rb +63 -0
- data/test/line_number_test.rb +80 -0
- data/test/measure_allocations_test.rb +26 -0
- data/test/measure_cpu_time_test.rb +212 -0
- data/test/measure_gc_runs_test.rb +32 -0
- data/test/measure_gc_time_test.rb +36 -0
- data/test/measure_memory_test.rb +33 -0
- data/test/measure_process_time_test.rb +61 -0
- data/test/measure_wall_time_test.rb +255 -0
- data/test/method_elimination_test.rb +84 -0
- data/test/module_test.rb +45 -0
- data/test/multi_printer_test.rb +104 -0
- data/test/no_method_class_test.rb +15 -0
- data/test/pause_resume_test.rb +166 -0
- data/test/prime.rb +54 -0
- data/test/printers_test.rb +275 -0
- data/test/printing_recursive_graph_test.rb +127 -0
- data/test/rack_test.rb +157 -0
- data/test/recursive_test.rb +215 -0
- data/test/singleton_test.rb +38 -0
- data/test/stack_printer_test.rb +77 -0
- data/test/stack_test.rb +138 -0
- data/test/start_stop_test.rb +112 -0
- data/test/test_helper.rb +267 -0
- data/test/thread_test.rb +187 -0
- data/test/unique_call_path_test.rb +202 -0
- data/test/yarv_test.rb +55 -0
- metadata +199 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
# The call info visitor class does a depth-first traversal across a
|
2
|
+
# list of method infos. At each call_info node, the visitor executes
|
3
|
+
# the block provided in the #visit method. The block is passed two
|
4
|
+
# parameters, the event and the call_info instance. Event will be
|
5
|
+
# either :enter or :exit.
|
6
|
+
#
|
7
|
+
# visitor = RubyProf::CallInfoVisitor.new(result.threads.first.top_call_infos)
|
8
|
+
#
|
9
|
+
# method_names = Array.new
|
10
|
+
#
|
11
|
+
# visitor.visit do |call_info, event|
|
12
|
+
# method_names << call_info.target.full_name if event == :enter
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# puts method_names
|
16
|
+
|
17
|
+
module RubyProf
|
18
|
+
class CallInfoVisitor
|
19
|
+
|
20
|
+
def initialize(call_infos)
|
21
|
+
@call_infos = CallInfo.roots_of(call_infos)
|
22
|
+
end
|
23
|
+
|
24
|
+
def visit(&block)
|
25
|
+
@call_infos.each do |call_info|
|
26
|
+
visit_call_info(call_info, &block)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
def visit_call_info(call_info, &block)
|
32
|
+
yield call_info, :enter
|
33
|
+
call_info.children.each do |child|
|
34
|
+
visit_call_info(child, &block)
|
35
|
+
end
|
36
|
+
yield call_info, :exit
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# These methods are here for backwards compatability with previous RubyProf releases
|
4
|
+
module RubyProf
|
5
|
+
# Measurements
|
6
|
+
def self.cpu_frequency
|
7
|
+
Measure::CpuTime.frequency
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.measure_allocations
|
11
|
+
Measure::Allocations.measure
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.measure_cpu_time
|
15
|
+
Measure::CpuTime.measure
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.measure_gc_runs
|
19
|
+
Measure::GcRuns.measure
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.measure_gc_time
|
23
|
+
Measure::GcTime.measure
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.measure_memory
|
27
|
+
Measure::Memory.measure
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.measure_process_time
|
31
|
+
Measure::ProcessTime.measure
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.measure_wall_time
|
35
|
+
Measure::WallTime.measure
|
36
|
+
end
|
37
|
+
|
38
|
+
# call-seq:
|
39
|
+
# measure_mode -> measure_mode
|
40
|
+
#
|
41
|
+
# Returns what ruby-prof is measuring. Valid values include:
|
42
|
+
#
|
43
|
+
# *RubyProf::WALL_TIME - Measure wall time using gettimeofday on Linx and GetLocalTime on Windows. This is default.
|
44
|
+
# *RubyProf::PROCESS_TIME - Measure process time. It is implemented using the clock functions in the C Runtime library.
|
45
|
+
# *RubyProf::CPU_TIME - Measure time using the CPU clock counter. This mode is only supported on Pentium or PowerPC platforms.
|
46
|
+
# *RubyProf::ALLOCATIONS - Measure object allocations. This requires a patched Ruby interpreter.
|
47
|
+
# *RubyProf::MEMORY - Measure memory size. This requires a patched Ruby interpreter.
|
48
|
+
# *RubyProf::GC_RUNS - Measure number of garbage collections. This requires a patched Ruby interpreter.
|
49
|
+
# *RubyProf::GC_TIME - Measure time spent doing garbage collection. This requires a patched Ruby interpreter.*/
|
50
|
+
|
51
|
+
def self.measure_mode
|
52
|
+
@measure_mode ||= RubyProf::WALL_TIME
|
53
|
+
end
|
54
|
+
|
55
|
+
# call-seq:
|
56
|
+
# measure_mode=value -> void
|
57
|
+
#
|
58
|
+
# Specifies what ruby-prof should measure. Valid values include:
|
59
|
+
#
|
60
|
+
# *RubyProf::WALL_TIME - Measure wall time using gettimeofday on Linx and GetLocalTime on Windows. This is default.
|
61
|
+
# *RubyProf::PROCESS_TIME - Measure process time. It is implemented using the clock functions in the C Runtime library.
|
62
|
+
# *RubyProf::CPU_TIME - Measure time using the CPU clock counter. This mode is only supported on Pentium or PowerPC platforms.
|
63
|
+
# *RubyProf::ALLOCATIONS - Measure object allocations. This requires a patched Ruby interpreter.
|
64
|
+
# *RubyProf::MEMORY - Measure memory size. This requires a patched Ruby interpreter.
|
65
|
+
# *RubyProf::GC_RUNS - Measure number of garbage collections. This requires a patched Ruby interpreter.
|
66
|
+
# *RubyProf::GC_TIME - Measure time spent doing garbage collection. This requires a patched Ruby interpreter.*/
|
67
|
+
def self.measure_mode=(value)
|
68
|
+
@measure_mode = value
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.measure_mode_string
|
72
|
+
case measure_mode
|
73
|
+
when WALL_TIME then "wall_time"
|
74
|
+
when CPU_TIME then "cpu_time"
|
75
|
+
when PROCESS_TIME then "process_time_time"
|
76
|
+
when ALLOCATIONS then "allocations"
|
77
|
+
when MEMORY then "memory"
|
78
|
+
when GC_TIME then "gc_time"
|
79
|
+
when GC_RUNS then "gc_runs"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# call-seq:
|
84
|
+
# exclude_threads -> exclude_threads
|
85
|
+
#
|
86
|
+
# Returns threads ruby-prof should exclude from profiling
|
87
|
+
|
88
|
+
def self.exclude_threads
|
89
|
+
@exclude_threads ||= Array.new
|
90
|
+
end
|
91
|
+
|
92
|
+
# call-seq:
|
93
|
+
# exclude_threads= -> void
|
94
|
+
#
|
95
|
+
# Specifies what threads ruby-prof should exclude from profiling
|
96
|
+
|
97
|
+
def self.exclude_threads=(value)
|
98
|
+
@exclude_threads = value
|
99
|
+
end
|
100
|
+
|
101
|
+
# Profiling
|
102
|
+
def self.start_script(script)
|
103
|
+
start
|
104
|
+
load script
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.start
|
108
|
+
ensure_not_running!
|
109
|
+
@profile = Profile.new(measure_mode: measure_mode, exclude_threads: exclude_threads)
|
110
|
+
enable_gc_stats_if_needed
|
111
|
+
@profile.start
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.pause
|
115
|
+
ensure_running!
|
116
|
+
disable_gc_stats_if_needed
|
117
|
+
@profile.pause
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.running?
|
121
|
+
if defined?(@profile) and @profile
|
122
|
+
@profile.running?
|
123
|
+
else
|
124
|
+
false
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def self.resume
|
129
|
+
ensure_running!
|
130
|
+
enable_gc_stats_if_needed
|
131
|
+
@profile.resume
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.stop
|
135
|
+
ensure_running!
|
136
|
+
result = @profile.stop
|
137
|
+
disable_gc_stats_if_needed
|
138
|
+
@profile = nil
|
139
|
+
result
|
140
|
+
end
|
141
|
+
|
142
|
+
# Profile a block
|
143
|
+
def self.profile(options = {}, &block)
|
144
|
+
ensure_not_running!
|
145
|
+
gc_stat_was_enabled = enable_gc_stats_if_needed
|
146
|
+
options = { measure_mode: measure_mode, exclude_threads: exclude_threads }.merge!(options)
|
147
|
+
result = Profile.profile(options, &block)
|
148
|
+
ensure
|
149
|
+
disable_gc_stats_if_needed(gc_stat_was_enabled)
|
150
|
+
result
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
private
|
155
|
+
def self.ensure_running!
|
156
|
+
raise(RuntimeError, "RubyProf.start was not yet called") unless running?
|
157
|
+
end
|
158
|
+
|
159
|
+
def self.ensure_not_running!
|
160
|
+
raise(RuntimeError, "RubyProf is already running") if running?
|
161
|
+
end
|
162
|
+
|
163
|
+
# for GC.allocated_size to work GC statistics should be enabled
|
164
|
+
def self.enable_gc_stats_if_needed
|
165
|
+
if measure_mode_requires_gc_stats_enabled?
|
166
|
+
@gc_stat_was_enabled = GC.enable_stats
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def self.disable_gc_stats_if_needed(was_enabled=nil)
|
171
|
+
was_enabled ||= defined?(@gc_stat_was_enabled) && @gc_stat_was_enabled
|
172
|
+
GC.disable_stats if measure_mode_requires_gc_stats_enabled? && !was_enabled
|
173
|
+
end
|
174
|
+
|
175
|
+
def self.measure_mode_requires_gc_stats_enabled?
|
176
|
+
GC.respond_to?(:enable_stats) &&
|
177
|
+
[RubyProf::MEMORY, RubyProf::GC_TIME, RubyProf::GC_RUNS].include?(measure_mode)
|
178
|
+
end
|
179
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module RubyProf
|
4
|
+
class MethodInfo
|
5
|
+
include Comparable
|
6
|
+
|
7
|
+
def <=>(other)
|
8
|
+
if self.total_time < other.total_time
|
9
|
+
-1
|
10
|
+
elsif self.total_time > other.total_time
|
11
|
+
1
|
12
|
+
elsif self.min_depth < other.min_depth
|
13
|
+
1
|
14
|
+
elsif self.min_depth > other.min_depth
|
15
|
+
-1
|
16
|
+
else
|
17
|
+
self.full_name <=> other.full_name
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def called
|
22
|
+
@called ||= begin
|
23
|
+
call_infos.inject(0) do |sum, call_info|
|
24
|
+
sum + call_info.called
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def total_time
|
30
|
+
@total_time ||= begin
|
31
|
+
call_infos.inject(0) do |sum, call_info|
|
32
|
+
sum += call_info.total_time if !call_info.recursive?
|
33
|
+
sum
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self_time
|
39
|
+
@self_time ||= begin
|
40
|
+
call_infos.inject(0) do |sum, call_info|
|
41
|
+
sum += call_info.self_time if !call_info.recursive?
|
42
|
+
sum
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def wait_time
|
48
|
+
@wait_time ||= begin
|
49
|
+
call_infos.inject(0) do |sum, call_info|
|
50
|
+
sum += call_info.wait_time if !call_info.recursive?
|
51
|
+
sum
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def children_time
|
57
|
+
@children_time ||= begin
|
58
|
+
call_infos.inject(0) do |sum, call_info|
|
59
|
+
sum += call_info.children_time if !call_info.recursive?
|
60
|
+
sum
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def min_depth
|
66
|
+
@min_depth ||= call_infos.map(&:depth).min
|
67
|
+
end
|
68
|
+
|
69
|
+
def root?
|
70
|
+
@root ||= begin
|
71
|
+
call_infos.find do |call_info|
|
72
|
+
not call_info.root?
|
73
|
+
end.nil?
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def children
|
78
|
+
@children ||= call_infos.map(&:children).flatten
|
79
|
+
end
|
80
|
+
|
81
|
+
def parents
|
82
|
+
@parents ||= call_infos.map(&:parent)
|
83
|
+
end
|
84
|
+
|
85
|
+
def aggregate_parents
|
86
|
+
# group call infos based on their parents
|
87
|
+
groups = self.call_infos.each_with_object({}) do |call_info, hash|
|
88
|
+
key = call_info.parent ? call_info.parent.target : self
|
89
|
+
(hash[key] ||= []) << call_info
|
90
|
+
end
|
91
|
+
|
92
|
+
groups.map do |key, value|
|
93
|
+
AggregateCallInfo.new(value, self)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def aggregate_children
|
98
|
+
# group call infos based on their targets
|
99
|
+
groups = self.children.each_with_object({}) do |call_info, hash|
|
100
|
+
key = call_info.target
|
101
|
+
(hash[key] ||= []) << call_info
|
102
|
+
end
|
103
|
+
|
104
|
+
groups.map do |key, value|
|
105
|
+
AggregateCallInfo.new(value, self)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def to_s
|
110
|
+
"#{self.full_name} (c: #{self.called}, tt: #{self.total_time}, st: #{self.self_time}, wt: #{wait_time}, ct: #{self.children_time})"
|
111
|
+
end
|
112
|
+
|
113
|
+
# remove method from the call graph. should not be called directly.
|
114
|
+
def eliminate!
|
115
|
+
# $stderr.puts "eliminating #{self}"
|
116
|
+
call_infos.each{ |call_info| call_info.eliminate! }
|
117
|
+
call_infos.clear
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module RubyProf
|
4
|
+
class AbstractPrinter
|
5
|
+
# Create a new printer.
|
6
|
+
#
|
7
|
+
# result should be the output generated from a profiling run
|
8
|
+
def initialize(result)
|
9
|
+
@result = result
|
10
|
+
@output = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
# Specify print options.
|
14
|
+
#
|
15
|
+
# options - Hash table
|
16
|
+
# :min_percent - Number 0 to 100 that specifes the minimum
|
17
|
+
# %self (the methods self time divided by the
|
18
|
+
# overall total time) that a method must take
|
19
|
+
# for it to be printed out in the report.
|
20
|
+
# Default value is 0.
|
21
|
+
#
|
22
|
+
# :print_file - True or false. Specifies if a method's source
|
23
|
+
# file should be printed. Default value if false.
|
24
|
+
#
|
25
|
+
# :sort_method - Specifies method used for sorting method infos.
|
26
|
+
# Available values are :total_time, :self_time,
|
27
|
+
# :wait_time, :children_time
|
28
|
+
# Default value is :total_time
|
29
|
+
# :editor_uri - Specifies editor uri scheme used for opening files
|
30
|
+
# e.g. :atm or :mvim. For OS X default is :txmt.
|
31
|
+
# Pass false to print bare filenames.
|
32
|
+
# Use RUBY_PROF_EDITOR_URI environment variable to override.
|
33
|
+
def setup_options(options = {})
|
34
|
+
@options = options
|
35
|
+
end
|
36
|
+
|
37
|
+
def min_percent
|
38
|
+
@options[:min_percent] || 0
|
39
|
+
end
|
40
|
+
|
41
|
+
def print_file
|
42
|
+
@options[:print_file] || false
|
43
|
+
end
|
44
|
+
|
45
|
+
def sort_method
|
46
|
+
@options[:sort_method] || :total_time
|
47
|
+
end
|
48
|
+
|
49
|
+
def editor_uri
|
50
|
+
if ENV.key?('RUBY_PROF_EDITOR_URI')
|
51
|
+
ENV['RUBY_PROF_EDITOR_URI'] || false
|
52
|
+
elsif @options.key?(:editor_uri)
|
53
|
+
@options[:editor_uri]
|
54
|
+
else
|
55
|
+
RUBY_PLATFORM =~ /darwin/ ? 'txmt' : false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def method_name(method)
|
60
|
+
name = method.full_name
|
61
|
+
if print_file
|
62
|
+
name += " (#{method.source_file}:#{method.line}}"
|
63
|
+
end
|
64
|
+
name
|
65
|
+
end
|
66
|
+
|
67
|
+
# Print a profiling report to the provided output.
|
68
|
+
#
|
69
|
+
# output - Any IO object, including STDOUT or a file.
|
70
|
+
# The default value is STDOUT.
|
71
|
+
#
|
72
|
+
# options - Hash of print options. See #setup_options
|
73
|
+
# for more information. Note that each printer can
|
74
|
+
# define its own set of options.
|
75
|
+
def print(output = STDOUT, options = {})
|
76
|
+
@output = output
|
77
|
+
setup_options(options)
|
78
|
+
print_threads
|
79
|
+
end
|
80
|
+
|
81
|
+
def print_threads
|
82
|
+
@result.threads.each do |thread|
|
83
|
+
print_thread(thread)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def print_thread(thread)
|
88
|
+
print_header(thread)
|
89
|
+
print_methods(thread)
|
90
|
+
print_footer(thread)
|
91
|
+
end
|
92
|
+
|
93
|
+
def print_header(thread)
|
94
|
+
end
|
95
|
+
|
96
|
+
def print_footer(thread)
|
97
|
+
end
|
98
|
+
|
99
|
+
# whether this printer need a :path option pointing to a directory
|
100
|
+
def self.needs_dir?
|
101
|
+
false
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module RubyProf
|
4
|
+
# Prints out the call graph based on CallInfo instances. This
|
5
|
+
# is mainly for debugging purposes as it provides access into
|
6
|
+
# into RubyProf's internals.
|
7
|
+
|
8
|
+
class CallInfoPrinter < AbstractPrinter
|
9
|
+
TIME_WIDTH = 0
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def print_header(thread)
|
14
|
+
@output << "Thread ID: #{thread.id}\n"
|
15
|
+
@output << "Fiber ID: #{thread.fiber_id}\n"
|
16
|
+
@output << "Total Time: #{thread.total_time}\n"
|
17
|
+
@output << "Sort by: #{sort_method}\n"
|
18
|
+
@output << "\n"
|
19
|
+
end
|
20
|
+
|
21
|
+
def print_methods(thread)
|
22
|
+
visitor = CallInfoVisitor.new(thread.top_call_infos)
|
23
|
+
|
24
|
+
visitor.visit do |call_info, event|
|
25
|
+
if event == :enter
|
26
|
+
@output << " " * call_info.depth
|
27
|
+
@output << call_info.target.full_name
|
28
|
+
@output << " ("
|
29
|
+
@output << "tt:#{sprintf("%#{TIME_WIDTH}.2f", call_info.total_time)}, "
|
30
|
+
@output << "st:#{sprintf("%#{TIME_WIDTH}.2f", call_info.self_time)}, "
|
31
|
+
@output << "wt:#{sprintf("%#{TIME_WIDTH}.2f", call_info.wait_time)}, "
|
32
|
+
@output << "ct:#{sprintf("%#{TIME_WIDTH}.2f", call_info.children_time)}, "
|
33
|
+
@output << "call:#{call_info.called}, "
|
34
|
+
@output << "rec:#{call_info.recursive?}"
|
35
|
+
@output << ")"
|
36
|
+
@output << "\n"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|