ruby-prof 0.6.0-x86-mswin32-60 → 0.7.0-x86-mswin32-60
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.
- data/CHANGES +54 -1
- data/README +134 -7
- data/Rakefile +40 -58
- data/bin/ruby-prof +21 -6
- data/ext/extconf.rb +13 -0
- data/ext/measure_allocations.h +16 -1
- data/ext/measure_cpu_time.h +15 -3
- data/ext/measure_gc_runs.h +76 -0
- data/ext/measure_gc_time.h +57 -0
- data/ext/measure_memory.h +61 -2
- data/ext/measure_process_time.h +13 -2
- data/ext/measure_wall_time.h +12 -1
- data/ext/mingw/Rakefile +23 -0
- data/ext/mingw/build.rake +38 -0
- data/ext/mingw/ruby_prof.so +0 -0
- data/ext/ruby_prof.c +685 -633
- data/ext/ruby_prof.h +188 -0
- data/ext/vc/ruby_prof.sln +20 -0
- data/ext/vc/ruby_prof.vcproj +241 -0
- data/ext/version.h +4 -0
- data/lib/ruby-prof.rb +4 -0
- data/lib/ruby-prof/call_info.rb +47 -0
- data/lib/ruby-prof/call_tree_printer.rb +9 -1
- data/lib/ruby-prof/graph_html_printer.rb +6 -5
- data/lib/ruby-prof/graph_printer.rb +3 -2
- data/lib/ruby-prof/method_info.rb +85 -0
- data/lib/ruby-prof/task.rb +1 -2
- data/lib/ruby-prof/test.rb +148 -0
- data/rails/environment/profile.rb +24 -0
- data/rails/example/example_test.rb +9 -0
- data/rails/profile_test_helper.rb +21 -0
- data/test/basic_test.rb +173 -80
- data/test/duplicate_names_test.rb +2 -3
- data/test/exceptions_test.rb +15 -0
- data/test/exclude_threads_test.rb +54 -0
- data/test/line_number_test.rb +18 -14
- data/test/measurement_test.rb +121 -0
- data/test/module_test.rb +5 -8
- data/test/no_method_class_test.rb +4 -5
- data/test/prime.rb +3 -5
- data/test/prime_test.rb +1 -12
- data/test/printers_test.rb +10 -13
- data/test/profile_unit_test.rb +10 -12
- data/test/recursive_test.rb +202 -92
- data/test/singleton_test.rb +1 -2
- data/test/stack_test.rb +138 -0
- data/test/start_stop_test.rb +95 -0
- data/test/test_suite.rb +7 -3
- data/test/thread_test.rb +111 -87
- data/test/unique_call_path_test.rb +206 -0
- metadata +42 -44
- data/ext/extconf.rb.rej +0 -13
- data/lib/ruby-prof/call_tree_printer.rb.rej +0 -27
- data/lib/ruby-prof/profile_test_case.rb +0 -80
- data/lib/ruby_prof.so +0 -0
- data/rails_plugin/ruby-prof/init.rb +0 -8
- data/rails_plugin/ruby-prof/lib/profiling.rb +0 -57
- data/test/measure_mode_test.rb +0 -79
- data/test/prime1.rb +0 -17
- data/test/prime2.rb +0 -26
- data/test/prime3.rb +0 -17
- data/test/start_test.rb +0 -24
- data/test/test_helper.rb +0 -55
- data/test/timing_test.rb +0 -133
data/ext/version.h
ADDED
data/lib/ruby-prof.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
require "ruby_prof.so"
|
2
2
|
|
3
|
+
require "ruby-prof/method_info"
|
4
|
+
require "ruby-prof/call_info"
|
3
5
|
require "ruby-prof/flat_printer"
|
4
6
|
require "ruby-prof/graph_printer"
|
5
7
|
require "ruby-prof/graph_html_printer"
|
6
8
|
require "ruby-prof/call_tree_printer"
|
7
9
|
|
10
|
+
require "ruby-prof/test"
|
11
|
+
|
8
12
|
module RubyProf
|
9
13
|
# See if the user specified the clock mode via
|
10
14
|
# the RUBY_PROF_MEASURE_MODE environment variable
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module RubyProf
|
2
|
+
class CallInfo
|
3
|
+
def depth
|
4
|
+
result = 0
|
5
|
+
call_info = self.parent
|
6
|
+
|
7
|
+
while call_info
|
8
|
+
result += 1
|
9
|
+
call_info = call_info.parent
|
10
|
+
end
|
11
|
+
result
|
12
|
+
end
|
13
|
+
|
14
|
+
def children_time
|
15
|
+
children.inject(0) do |sum, call_info|
|
16
|
+
sum += call_info.total_time
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def stack
|
21
|
+
@stack ||= begin
|
22
|
+
methods = Array.new
|
23
|
+
call_info = self
|
24
|
+
|
25
|
+
while call_info
|
26
|
+
methods << call_info.target
|
27
|
+
call_info = call_info.parent
|
28
|
+
end
|
29
|
+
methods.reverse
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def call_sequence
|
34
|
+
@call_sequence ||= begin
|
35
|
+
stack.map {|method| method.full_name}.join('->')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def root?
|
40
|
+
self.parent.nil?
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_s
|
44
|
+
"#{call_sequence}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -27,8 +27,16 @@ module RubyProf
|
|
27
27
|
when RubyProf.const_defined?(:MEMORY) && RubyProf::MEMORY
|
28
28
|
@value_scale = 1
|
29
29
|
@output << 'memory'
|
30
|
+
when RubyProf.const_defined?(:GC_RUNS) && RubyProf::GC_RUNS
|
31
|
+
@value_scale = 1
|
32
|
+
@output << 'gc_runs'
|
33
|
+
when RubyProf.const_defined?(:GC_TIME) && RubyProf::GC_TIME
|
34
|
+
@value_scale = 1000000
|
35
|
+
@output << 'gc_time'
|
36
|
+
else
|
37
|
+
raise "Unknown measure mode: #{RubyProf.measure_mode}"
|
30
38
|
end
|
31
|
-
@output << "\n\n"
|
39
|
+
@output << "\n\n"
|
32
40
|
|
33
41
|
print_threads
|
34
42
|
end
|
@@ -115,6 +115,7 @@ module RubyProf
|
|
115
115
|
font-family: Verdana, Arial, Helvetica, sans-serif;
|
116
116
|
font-size: 9pt;
|
117
117
|
line-height: normal;
|
118
|
+
width: 100%;
|
118
119
|
}
|
119
120
|
|
120
121
|
th {
|
@@ -152,7 +153,6 @@ module RubyProf
|
|
152
153
|
|
153
154
|
.method_name {
|
154
155
|
text-align: left;
|
155
|
-
max-width: 25em;
|
156
156
|
}
|
157
157
|
</style>
|
158
158
|
</head>
|
@@ -198,8 +198,9 @@ module RubyProf
|
|
198
198
|
self_percentage = (method.self_time/total_time) * 100 %>
|
199
199
|
|
200
200
|
<!-- Parents -->
|
201
|
-
<% for caller in method.
|
202
|
-
|
201
|
+
<% for caller in method.call_infos
|
202
|
+
next unless caller.parent
|
203
|
+
next if min_time && caller.total_time < min_time %>
|
203
204
|
<tr>
|
204
205
|
<td> </td>
|
205
206
|
<td> </td>
|
@@ -209,8 +210,8 @@ module RubyProf
|
|
209
210
|
<td><%= sprintf("%#{TIME_WIDTH}.2f", caller.children_time) %></td>
|
210
211
|
<% called = "#{caller.called}/#{method.called}" %>
|
211
212
|
<td><%= sprintf("%#{CALL_WIDTH}s", called) %></td>
|
212
|
-
<td class="method_name"><%= create_link(thread_id, caller.target) %></td>
|
213
|
-
<td><a href="file://<%=h srcfile=File.expand_path(caller.target.source_file) %>#line=<%= linenum=caller.line %>" title="<%=h srcfile %>:<%= linenum %>"><%= caller.line %></a></td>
|
213
|
+
<td class="method_name"><%= create_link(thread_id, caller.parent.target) %></td>
|
214
|
+
<td><a href="file://<%=h srcfile=File.expand_path(caller.parent.target.source_file) %>#line=<%= linenum=caller.line %>" title="<%=h srcfile %>:<%= linenum %>"><%= caller.line %></a></td>
|
214
215
|
</tr>
|
215
216
|
<% end %>
|
216
217
|
|
@@ -127,7 +127,8 @@ module RubyProf
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def print_parents(thread_id, method)
|
130
|
-
method.
|
130
|
+
method.call_infos.each do |caller|
|
131
|
+
next unless caller.parent
|
131
132
|
@output << " " * 2 * PERCENTAGE_WIDTH
|
132
133
|
@output << sprintf("%#{TIME_WIDTH}.2f", caller.total_time)
|
133
134
|
@output << sprintf("%#{TIME_WIDTH}.2f", caller.self_time)
|
@@ -136,7 +137,7 @@ module RubyProf
|
|
136
137
|
|
137
138
|
call_called = "#{caller.called}/#{method.called}"
|
138
139
|
@output << sprintf("%#{CALL_WIDTH}s", call_called)
|
139
|
-
@output << sprintf(" %s", caller.target.full_name)
|
140
|
+
@output << sprintf(" %s", caller.parent.target.full_name)
|
140
141
|
@output << "\n"
|
141
142
|
end
|
142
143
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module RubyProf
|
2
|
+
class MethodInfo
|
3
|
+
include Comparable
|
4
|
+
|
5
|
+
def <=>(other)
|
6
|
+
if self.total_time < other.total_time
|
7
|
+
-1
|
8
|
+
elsif self.total_time > other.total_time
|
9
|
+
1
|
10
|
+
elsif self.min_depth < other.min_depth
|
11
|
+
1
|
12
|
+
elsif self.min_depth > other.min_depth
|
13
|
+
-1
|
14
|
+
else
|
15
|
+
-1 * (self.full_name <=> other.full_name)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def called
|
20
|
+
@called ||= begin
|
21
|
+
call_infos.inject(0) do |sum, call_info|
|
22
|
+
sum += call_info.called
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def total_time
|
28
|
+
@total_time ||= begin
|
29
|
+
call_infos.inject(0) do |sum, call_info|
|
30
|
+
sum += call_info.total_time
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self_time
|
36
|
+
@self_time ||= begin
|
37
|
+
call_infos.inject(0) do |sum, call_info|
|
38
|
+
sum += call_info.self_time
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def wait_time
|
44
|
+
@wait_time ||= begin
|
45
|
+
call_infos.inject(0) do |sum, call_info|
|
46
|
+
sum += call_info.wait_time
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def children
|
52
|
+
@children ||= begin
|
53
|
+
call_infos.map do |call_info|
|
54
|
+
call_info.children
|
55
|
+
end.flatten
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def children_time
|
60
|
+
@children_time ||= begin
|
61
|
+
call_infos.inject(0) do |sum, call_info|
|
62
|
+
sum += call_info.children_time
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def min_depth
|
68
|
+
call_infos.map do |call_info|
|
69
|
+
call_info.depth
|
70
|
+
end.min
|
71
|
+
end
|
72
|
+
|
73
|
+
def root?
|
74
|
+
@root ||= begin
|
75
|
+
call_infos.find do |call_info|
|
76
|
+
not call_info.root?
|
77
|
+
end.nil?
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def to_s
|
82
|
+
full_name
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/ruby-prof/task.rb
CHANGED
@@ -0,0 +1,148 @@
|
|
1
|
+
# Now load ruby-prof and away we go
|
2
|
+
require 'fileutils'
|
3
|
+
require 'ruby-prof'
|
4
|
+
require 'benchmark'
|
5
|
+
|
6
|
+
module RubyProf
|
7
|
+
module Test
|
8
|
+
PROFILE_OPTIONS = {
|
9
|
+
:measure_modes => [RubyProf::PROCESS_TIME],
|
10
|
+
:count => 10,
|
11
|
+
:printers => [RubyProf::FlatPrinter, RubyProf::GraphHtmlPrinter],
|
12
|
+
:min_percent => 0.05,
|
13
|
+
:output_dir => Dir.pwd }
|
14
|
+
|
15
|
+
def output_dir
|
16
|
+
PROFILE_OPTIONS[:output_dir]
|
17
|
+
end
|
18
|
+
|
19
|
+
def run(result)
|
20
|
+
return if @method_name.to_s == "default_test"
|
21
|
+
|
22
|
+
yield(self.class::STARTED, name)
|
23
|
+
@_result = result
|
24
|
+
run_warmup
|
25
|
+
PROFILE_OPTIONS[:measure_modes].each do |measure_mode|
|
26
|
+
data = run_profile(measure_mode)
|
27
|
+
report_profile(data, measure_mode)
|
28
|
+
result.add_run
|
29
|
+
end
|
30
|
+
yield(self.class::FINISHED, name)
|
31
|
+
end
|
32
|
+
|
33
|
+
def run_test
|
34
|
+
begin
|
35
|
+
setup
|
36
|
+
yield
|
37
|
+
rescue ::Test::Unit::AssertionFailedError => e
|
38
|
+
add_failure(e.message, e.backtrace)
|
39
|
+
rescue StandardError, ScriptError
|
40
|
+
add_error($!)
|
41
|
+
ensure
|
42
|
+
begin
|
43
|
+
teardown
|
44
|
+
rescue ::Test::Unit::AssertionFailedError => e
|
45
|
+
add_failure(e.message, e.backtrace)
|
46
|
+
rescue StandardError, ScriptError
|
47
|
+
add_error($!)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def run_warmup
|
53
|
+
print "\n#{self.class.name}##{method_name}"
|
54
|
+
|
55
|
+
run_test do
|
56
|
+
bench = Benchmark.realtime do
|
57
|
+
__send__(@method_name)
|
58
|
+
end
|
59
|
+
puts " (%.2fs warmup)" % bench
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def run_profile(measure_mode)
|
64
|
+
RubyProf.measure_mode = measure_mode
|
65
|
+
|
66
|
+
print ' '
|
67
|
+
PROFILE_OPTIONS[:count].times do |i|
|
68
|
+
run_test do
|
69
|
+
begin
|
70
|
+
print '.'
|
71
|
+
$stdout.flush
|
72
|
+
GC.disable
|
73
|
+
|
74
|
+
RubyProf.resume do
|
75
|
+
__send__(@method_name)
|
76
|
+
end
|
77
|
+
ensure
|
78
|
+
GC.enable
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
data = RubyProf.stop
|
84
|
+
bench = data.threads.values.inject(0) do |total, method_infos|
|
85
|
+
top = method_infos.sort.last
|
86
|
+
total += top.total_time
|
87
|
+
total
|
88
|
+
end
|
89
|
+
|
90
|
+
puts "\n #{measure_mode_name(measure_mode)}: #{format_profile_total(bench, measure_mode)}\n"
|
91
|
+
|
92
|
+
data
|
93
|
+
end
|
94
|
+
|
95
|
+
def format_profile_total(total, measure_mode)
|
96
|
+
case measure_mode
|
97
|
+
when RubyProf::PROCESS_TIME, RubyProf::WALL_TIME
|
98
|
+
"%.2f seconds" % total
|
99
|
+
when RubyProf::MEMORY
|
100
|
+
"%.2f kilobytes" % total
|
101
|
+
when RubyProf::ALLOCATIONS
|
102
|
+
"%d allocations" % total
|
103
|
+
else
|
104
|
+
"%.2f #{measure_mode}"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def report_profile(data, measure_mode)
|
109
|
+
PROFILE_OPTIONS[:printers].each do |printer_klass|
|
110
|
+
printer = printer_klass.new(data)
|
111
|
+
|
112
|
+
# Makes sure the output directory exits
|
113
|
+
FileUtils.mkdir_p(output_dir)
|
114
|
+
|
115
|
+
# Open the file
|
116
|
+
file_name = report_filename(printer, measure_mode)
|
117
|
+
|
118
|
+
File.open(file_name, 'wb') do |file|
|
119
|
+
printer.print(file, PROFILE_OPTIONS)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# The report filename is test_name + measure_mode + report_type
|
125
|
+
def report_filename(printer, measure_mode)
|
126
|
+
suffix =
|
127
|
+
case printer
|
128
|
+
when RubyProf::FlatPrinter; 'flat.txt'
|
129
|
+
when RubyProf::GraphPrinter; 'graph.txt'
|
130
|
+
when RubyProf::GraphHtmlPrinter; 'graph.html'
|
131
|
+
when RubyProf::CallTreePrinter; 'tree.txt'
|
132
|
+
else printer.to_s.downcase
|
133
|
+
end
|
134
|
+
|
135
|
+
"#{output_dir}/#{method_name}_#{measure_mode_name(measure_mode)}_#{suffix}"
|
136
|
+
end
|
137
|
+
|
138
|
+
def measure_mode_name(measure_mode)
|
139
|
+
case measure_mode
|
140
|
+
when RubyProf::PROCESS_TIME; 'process_time'
|
141
|
+
when RubyProf::WALL_TIME; 'wall_time'
|
142
|
+
when RubyProf::MEMORY; 'memory'
|
143
|
+
when RubyProf::ALLOCATIONS; 'allocations'
|
144
|
+
else "measure#{measure_mode}"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Settings specified here will take precedence over those in config/environment.rb
|
2
|
+
# The profile environment should match the same settings
|
3
|
+
# as the production environment to give a reasonalbe
|
4
|
+
# approximation of performance. However, it should
|
5
|
+
# definitely not use the production databse!
|
6
|
+
|
7
|
+
|
8
|
+
# Cache classes - otherwise your code
|
9
|
+
# will run approximately 5 times slower and the
|
10
|
+
# profiling results will be overwhelmed by Rails
|
11
|
+
# dependency loading mechanism
|
12
|
+
config.cache_classes = true
|
13
|
+
|
14
|
+
# Don't check template timestamps - once again this
|
15
|
+
# is to avoid IO times overwhelming profile results
|
16
|
+
config.action_view.cache_template_loading = true
|
17
|
+
|
18
|
+
# This is debatable, but turn off action controller
|
19
|
+
# caching to see how long it really takes to run
|
20
|
+
# queries and render templates
|
21
|
+
config.action_controller.perform_caching = false
|
22
|
+
|
23
|
+
# Turn off most logging
|
24
|
+
config.log_level = :info
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Load profile environment
|
2
|
+
env = ENV["RAILS_ENV"] = "profile"
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
|
4
|
+
|
5
|
+
# Load Rails testing infrastructure
|
6
|
+
require 'test_help'
|
7
|
+
|
8
|
+
# Now we can load test_helper since we've already loaded the
|
9
|
+
# profile RAILS environment.
|
10
|
+
require File.expand_path(File.join(RAILS_ROOT, 'test', 'test_helper'))
|
11
|
+
|
12
|
+
# Reset the current environment back to profile
|
13
|
+
# since test_helper reset it to test
|
14
|
+
ENV["RAILS_ENV"] = env
|
15
|
+
|
16
|
+
# Now load ruby-prof and away we go
|
17
|
+
require 'ruby-prof'
|
18
|
+
|
19
|
+
# Setup output directory to Rails tmp directory
|
20
|
+
RubyProf::Test::PROFILE_OPTIONS[:output_dir] =
|
21
|
+
File.expand_path(File.join(RAILS_ROOT, 'tmp', 'profile'))
|
data/test/basic_test.rb
CHANGED
@@ -2,10 +2,6 @@
|
|
2
2
|
|
3
3
|
require 'test/unit'
|
4
4
|
require 'ruby-prof'
|
5
|
-
require 'test_helper'
|
6
|
-
|
7
|
-
# Need to use wall time for this test due to the sleep calls
|
8
|
-
RubyProf::measure_mode = RubyProf::WALL_TIME
|
9
5
|
|
10
6
|
class C1
|
11
7
|
def C1.hello
|
@@ -55,6 +51,11 @@ class C6
|
|
55
51
|
end
|
56
52
|
|
57
53
|
class BasicTest < Test::Unit::TestCase
|
54
|
+
def setup
|
55
|
+
# Need to use wall time for this test due to the sleep calls
|
56
|
+
RubyProf::measure_mode = RubyProf::WALL_TIME
|
57
|
+
end
|
58
|
+
|
58
59
|
def test_running
|
59
60
|
assert(!RubyProf.running?)
|
60
61
|
RubyProf.start
|
@@ -62,13 +63,13 @@ class BasicTest < Test::Unit::TestCase
|
|
62
63
|
RubyProf.stop
|
63
64
|
assert(!RubyProf.running?)
|
64
65
|
end
|
65
|
-
|
66
|
+
|
66
67
|
def test_double_profile
|
67
68
|
RubyProf.start
|
68
69
|
assert_raise(RuntimeError) do
|
69
70
|
RubyProf.start
|
70
71
|
end
|
71
|
-
|
72
|
+
|
72
73
|
assert_raise(RuntimeError) do
|
73
74
|
RubyProf.profile do
|
74
75
|
puts 1
|
@@ -76,115 +77,207 @@ class BasicTest < Test::Unit::TestCase
|
|
76
77
|
end
|
77
78
|
RubyProf.stop
|
78
79
|
end
|
79
|
-
|
80
|
+
|
80
81
|
def test_no_block
|
81
82
|
assert_raise(ArgumentError) do
|
82
83
|
RubyProf.profile
|
83
84
|
end
|
84
85
|
end
|
85
|
-
|
86
|
-
def
|
86
|
+
|
87
|
+
def test_class_methods
|
87
88
|
result = RubyProf.profile do
|
88
89
|
C1.hello
|
89
|
-
C1.new.hello
|
90
90
|
end
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
#
|
95
|
-
#
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
# 1 for Object hello
|
101
|
-
# 1 sleep
|
102
|
-
assert_equal(7, methods.length)
|
103
|
-
|
91
|
+
|
92
|
+
# Length should be 3:
|
93
|
+
# BasicTest#test_class_methods
|
94
|
+
# <Class::C1>#hello
|
95
|
+
# Kernel#sleep
|
96
|
+
|
97
|
+
methods = result.threads.values.first.sort.reverse
|
98
|
+
assert_equal(3, methods.length)
|
99
|
+
|
104
100
|
# Check the names
|
105
|
-
|
106
|
-
|
107
|
-
assert_equal('
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
101
|
+
assert_equal('BasicTest#test_class_methods', methods[0].full_name)
|
102
|
+
assert_equal('<Class::C1>#hello', methods[1].full_name)
|
103
|
+
assert_equal('Kernel#sleep', methods[2].full_name)
|
104
|
+
|
105
|
+
# Check times
|
106
|
+
assert_in_delta(0.1, methods[0].total_time, 0.01)
|
107
|
+
assert_in_delta(0, methods[0].wait_time, 0.01)
|
108
|
+
assert_in_delta(0, methods[0].self_time, 0.01)
|
109
|
+
|
110
|
+
assert_in_delta(0.1, methods[1].total_time, 0.01)
|
111
|
+
assert_in_delta(0, methods[1].wait_time, 0.01)
|
112
|
+
assert_in_delta(0, methods[1].self_time, 0.01)
|
113
|
+
|
114
|
+
assert_in_delta(0.1, methods[2].total_time, 0.01)
|
115
|
+
assert_in_delta(0, methods[2].wait_time, 0.01)
|
116
|
+
assert_in_delta(0.1, methods[2].self_time, 0.01)
|
120
117
|
end
|
121
|
-
|
118
|
+
|
119
|
+
def test_instance_methods
|
120
|
+
result = RubyProf.profile do
|
121
|
+
C1.new.hello
|
122
|
+
end
|
123
|
+
|
124
|
+
# Methods called
|
125
|
+
# BasicTest#test_instance_methods
|
126
|
+
# Class.new
|
127
|
+
# Class:Object#allocate
|
128
|
+
# for Object#initialize
|
129
|
+
# C1#hello
|
130
|
+
# Kernel#sleep
|
131
|
+
|
132
|
+
methods = result.threads.values.first.sort.reverse
|
133
|
+
assert_equal(6, methods.length)
|
134
|
+
|
135
|
+
assert_equal('BasicTest#test_instance_methods', methods[0].full_name)
|
136
|
+
assert_equal('C1#hello', methods[1].full_name)
|
137
|
+
assert_equal('Kernel#sleep', methods[2].full_name)
|
138
|
+
assert_equal('Class#new', methods[3].full_name)
|
139
|
+
assert_equal('<Class::Object>#allocate', methods[4].full_name)
|
140
|
+
assert_equal('Object#initialize', methods[5].full_name)
|
141
|
+
|
142
|
+
# Check times
|
143
|
+
assert_in_delta(0.2, methods[0].total_time, 0.01)
|
144
|
+
assert_in_delta(0, methods[0].wait_time, 0.01)
|
145
|
+
assert_in_delta(0, methods[0].self_time, 0.01)
|
146
|
+
|
147
|
+
assert_in_delta(0.2, methods[1].total_time, 0.01)
|
148
|
+
assert_in_delta(0, methods[1].wait_time, 0.01)
|
149
|
+
assert_in_delta(0, methods[1].self_time, 0.01)
|
150
|
+
|
151
|
+
assert_in_delta(0.2, methods[2].total_time, 0.01)
|
152
|
+
assert_in_delta(0, methods[2].wait_time, 0.01)
|
153
|
+
assert_in_delta(0.2, methods[2].self_time, 0.01)
|
154
|
+
|
155
|
+
assert_in_delta(0, methods[3].total_time, 0.01)
|
156
|
+
assert_in_delta(0, methods[3].wait_time, 0.01)
|
157
|
+
assert_in_delta(0, methods[3].self_time, 0.01)
|
158
|
+
|
159
|
+
assert_in_delta(0, methods[4].total_time, 0.01)
|
160
|
+
assert_in_delta(0, methods[4].wait_time, 0.01)
|
161
|
+
assert_in_delta(0, methods[4].self_time, 0.01)
|
162
|
+
|
163
|
+
assert_in_delta(0, methods[5].total_time, 0.01)
|
164
|
+
assert_in_delta(0, methods[5].wait_time, 0.01)
|
165
|
+
assert_in_delta(0, methods[5].self_time, 0.01)
|
166
|
+
end
|
167
|
+
|
122
168
|
def test_module_methods
|
123
169
|
result = RubyProf.profile do
|
124
170
|
C2.hello
|
171
|
+
end
|
172
|
+
|
173
|
+
# Methods:
|
174
|
+
# BasicTest#test_module_methods
|
175
|
+
# M1#hello
|
176
|
+
# Kernel#sleep
|
177
|
+
|
178
|
+
methods = result.threads.values.first.sort.reverse
|
179
|
+
assert_equal(3, methods.length)
|
180
|
+
|
181
|
+
assert_equal('BasicTest#test_module_methods', methods[0].full_name)
|
182
|
+
assert_equal('M1#hello', methods[1].full_name)
|
183
|
+
assert_equal('Kernel#sleep', methods[2].full_name)
|
184
|
+
|
185
|
+
# Check times
|
186
|
+
assert_in_delta(0.3, methods[0].total_time, 0.01)
|
187
|
+
assert_in_delta(0, methods[0].wait_time, 0.01)
|
188
|
+
assert_in_delta(0, methods[0].self_time, 0.01)
|
189
|
+
|
190
|
+
assert_in_delta(0.3, methods[1].total_time, 0.01)
|
191
|
+
assert_in_delta(0, methods[1].wait_time, 0.01)
|
192
|
+
assert_in_delta(0, methods[1].self_time, 0.01)
|
193
|
+
|
194
|
+
assert_in_delta(0.3, methods[2].total_time, 0.01)
|
195
|
+
assert_in_delta(0, methods[2].wait_time, 0.01)
|
196
|
+
assert_in_delta(0.3, methods[2].self_time, 0.01)
|
197
|
+
end
|
198
|
+
|
199
|
+
def test_module_instance_methods
|
200
|
+
result = RubyProf.profile do
|
125
201
|
C2.new.hello
|
126
202
|
end
|
127
|
-
|
128
|
-
methods = result.threads.values.first
|
129
|
-
|
130
|
-
# Length should be 6:
|
131
|
-
# 1 BasicTest#test_module_methods (this method)
|
132
|
-
# 1 Class#new
|
133
|
-
# 1 <Class::Object>#allocate
|
134
|
-
# 1 Object#initialize
|
135
|
-
# 1 M1#hello
|
136
|
-
# 1 Kernel#sleep
|
137
203
|
|
204
|
+
# Methods:
|
205
|
+
# BasicTest#test_module_instance_methods
|
206
|
+
# Class#new
|
207
|
+
# <Class::Object>#allocate
|
208
|
+
# Object#initialize
|
209
|
+
# M1#hello
|
210
|
+
# Kernel#sleep
|
211
|
+
|
212
|
+
methods = result.threads.values.first.sort.reverse
|
138
213
|
assert_equal(6, methods.length)
|
139
214
|
|
140
|
-
#
|
141
|
-
|
142
|
-
|
143
|
-
assert_equal('
|
144
|
-
assert_equal('
|
145
|
-
assert_equal('
|
146
|
-
|
147
|
-
#
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
215
|
+
assert_equal('BasicTest#test_module_instance_methods', methods[0].full_name)
|
216
|
+
assert_equal('M1#hello', methods[1].full_name)
|
217
|
+
assert_equal('Kernel#sleep', methods[2].full_name)
|
218
|
+
assert_equal('Class#new', methods[3].full_name)
|
219
|
+
assert_equal('<Class::Object>#allocate', methods[4].full_name)
|
220
|
+
assert_equal('Object#initialize', methods[5].full_name)
|
221
|
+
|
222
|
+
# Check times
|
223
|
+
assert_in_delta(0.3, methods[0].total_time, 0.01)
|
224
|
+
assert_in_delta(0, methods[0].wait_time, 0.01)
|
225
|
+
assert_in_delta(0, methods[0].self_time, 0.01)
|
226
|
+
|
227
|
+
assert_in_delta(0.3, methods[1].total_time, 0.01)
|
228
|
+
assert_in_delta(0, methods[1].wait_time, 0.01)
|
229
|
+
assert_in_delta(0, methods[1].self_time, 0.01)
|
230
|
+
|
231
|
+
assert_in_delta(0.3, methods[2].total_time, 0.01)
|
232
|
+
assert_in_delta(0, methods[2].wait_time, 0.01)
|
233
|
+
assert_in_delta(0.3, methods[2].self_time, 0.01)
|
234
|
+
|
235
|
+
assert_in_delta(0, methods[3].total_time, 0.01)
|
236
|
+
assert_in_delta(0, methods[3].wait_time, 0.01)
|
237
|
+
assert_in_delta(0, methods[3].self_time, 0.01)
|
238
|
+
|
239
|
+
assert_in_delta(0, methods[4].total_time, 0.01)
|
240
|
+
assert_in_delta(0, methods[4].wait_time, 0.01)
|
241
|
+
assert_in_delta(0, methods[4].self_time, 0.01)
|
242
|
+
|
243
|
+
assert_in_delta(0, methods[5].total_time, 0.01)
|
244
|
+
assert_in_delta(0, methods[5].wait_time, 0.01)
|
245
|
+
assert_in_delta(0, methods[5].self_time, 0.01)
|
155
246
|
end
|
156
|
-
|
247
|
+
|
157
248
|
def test_singleton
|
158
249
|
c3 = C3.new
|
159
|
-
|
250
|
+
|
160
251
|
class << c3
|
161
252
|
def hello
|
162
253
|
end
|
163
254
|
end
|
164
|
-
|
255
|
+
|
165
256
|
result = RubyProf.profile do
|
166
257
|
c3.hello
|
167
258
|
end
|
168
|
-
|
169
|
-
methods = result.threads.values.first
|
170
|
-
|
171
|
-
# Length should be 2 - one for top level
|
172
|
-
# and one for the singleton method.
|
259
|
+
|
260
|
+
methods = result.threads.values.first.sort.reverse
|
173
261
|
assert_equal(2, methods.length)
|
174
|
-
|
175
|
-
# Check singleton method
|
176
|
-
methods = methods.sort.reverse
|
177
|
-
|
262
|
+
|
178
263
|
assert_equal('BasicTest#test_singleton', methods[0].full_name)
|
179
264
|
assert_equal('<Object::C3>#hello', methods[1].full_name)
|
265
|
+
|
266
|
+
assert_in_delta(0, methods[0].total_time, 0.01)
|
267
|
+
assert_in_delta(0, methods[0].wait_time, 0.01)
|
268
|
+
assert_in_delta(0, methods[0].self_time, 0.01)
|
269
|
+
|
270
|
+
assert_in_delta(0, methods[1].total_time, 0.01)
|
271
|
+
assert_in_delta(0, methods[1].wait_time, 0.01)
|
272
|
+
assert_in_delta(0, methods[1].self_time, 0.01)
|
180
273
|
end
|
181
|
-
|
274
|
+
|
182
275
|
def test_traceback
|
183
276
|
RubyProf.start
|
184
277
|
assert_raise(NoMethodError) do
|
185
278
|
RubyProf.xxx
|
186
279
|
end
|
187
|
-
|
280
|
+
|
188
281
|
RubyProf.stop
|
189
|
-
end
|
190
|
-
end
|
282
|
+
end
|
283
|
+
end
|