ruby-prof 0.8.2 → 0.9.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.
- data/CHANGES +23 -13
- data/{README → README.rdoc} +118 -111
- data/Rakefile +14 -26
- data/bin/ruby-prof +16 -4
- data/examples/empty.png +0 -0
- data/examples/graph.dot +106 -0
- data/examples/graph.png +0 -0
- data/examples/minus.png +0 -0
- data/examples/multi.flat.txt +23 -0
- data/examples/multi.graph.html +906 -0
- data/examples/multi.grind.dat +194 -0
- data/examples/multi.stack.html +573 -0
- data/examples/plus.png +0 -0
- data/examples/stack.html +573 -0
- data/ext/ruby_prof/extconf.rb +0 -1
- data/ext/ruby_prof/measure_allocations.h +6 -6
- data/ext/ruby_prof/measure_cpu_time.h +5 -5
- data/ext/ruby_prof/measure_gc_runs.h +1 -1
- data/ext/ruby_prof/measure_gc_time.h +1 -1
- data/ext/ruby_prof/measure_memory.h +4 -4
- data/ext/ruby_prof/measure_process_time.h +1 -1
- data/ext/ruby_prof/measure_wall_time.h +1 -1
- data/ext/ruby_prof/ruby_prof.c +240 -167
- data/ext/ruby_prof/ruby_prof.h +12 -10
- data/ext/ruby_prof/version.h +3 -3
- data/lib/ruby-prof.rb +7 -1
- data/lib/ruby-prof/abstract_printer.rb +5 -5
- data/lib/ruby-prof/aggregate_call_info.rb +9 -3
- data/lib/ruby-prof/call_info.rb +66 -1
- data/lib/ruby-prof/call_stack_printer.rb +751 -0
- data/lib/ruby-prof/call_tree_printer.rb +2 -2
- data/lib/ruby-prof/dot_printer.rb +151 -0
- data/lib/ruby-prof/empty.png +0 -0
- data/lib/ruby-prof/flat_printer.rb +16 -16
- data/lib/ruby-prof/flat_printer_with_line_numbers.rb +13 -13
- data/lib/ruby-prof/graph_html_printer.rb +58 -36
- data/lib/ruby-prof/graph_printer.rb +30 -30
- data/lib/ruby-prof/method_info.rb +24 -4
- data/lib/ruby-prof/minus.png +0 -0
- data/lib/ruby-prof/multi_printer.rb +54 -0
- data/lib/ruby-prof/plus.png +0 -0
- data/lib/ruby-prof/rack.rb +28 -0
- data/lib/ruby-prof/result.rb +70 -0
- data/lib/ruby-prof/symbol_to_proc.rb +1 -1
- data/lib/ruby-prof/task.rb +19 -19
- data/lib/ruby-prof/test.rb +3 -3
- data/lib/ruby_prof.so +0 -0
- data/rails/environment/profile.rb +2 -2
- data/rails/example/example_test.rb +2 -2
- data/rails/profile_test_helper.rb +1 -1
- data/test/aggregate_test.rb +21 -6
- data/test/basic_test.rb +3 -3
- data/test/duplicate_names_test.rb +2 -2
- data/test/enumerable_test.rb +2 -2
- data/test/exceptions_test.rb +2 -2
- data/test/exclude_threads_test.rb +45 -45
- data/test/exec_test.rb +2 -2
- data/test/line_number_test.rb +11 -11
- data/test/measurement_test.rb +4 -3
- data/test/method_elimination_test.rb +74 -0
- data/test/module_test.rb +7 -7
- data/test/multi_printer_test.rb +81 -0
- data/test/no_method_class_test.rb +2 -2
- data/test/prime.rb +7 -10
- data/test/printers_test.rb +57 -47
- data/test/recursive_test.rb +23 -62
- data/test/singleton_test.rb +3 -2
- data/test/stack_printer_test.rb +74 -0
- data/test/stack_test.rb +1 -1
- data/test/start_stop_test.rb +2 -2
- data/test/test_suite.rb +9 -0
- data/test/thread_test.rb +17 -17
- data/test/unique_call_path_test.rb +4 -4
- metadata +29 -8
data/test/singleton_test.rb
CHANGED
@@ -32,6 +32,7 @@ class SingletonTest < Test::Unit::TestCase
|
|
32
32
|
assert_equal(1, a.as.size)
|
33
33
|
end
|
34
34
|
printer = RubyProf::FlatPrinter.new(result)
|
35
|
-
|
35
|
+
output = ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT'] == "1" ? STDOUT : ''
|
36
|
+
printer.print(output)
|
36
37
|
end
|
37
|
-
end
|
38
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'ruby-prof'
|
5
|
+
require 'tmpdir'
|
6
|
+
|
7
|
+
# Test data
|
8
|
+
# A
|
9
|
+
# / \
|
10
|
+
# B C
|
11
|
+
# \
|
12
|
+
# B
|
13
|
+
|
14
|
+
class STPT
|
15
|
+
def a
|
16
|
+
100.times{b}
|
17
|
+
300.times{c}
|
18
|
+
c;c;c
|
19
|
+
end
|
20
|
+
|
21
|
+
def b
|
22
|
+
sleep 0
|
23
|
+
end
|
24
|
+
|
25
|
+
def c
|
26
|
+
5.times{b}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class StackPrinterTest < Test::Unit::TestCase
|
31
|
+
def setup
|
32
|
+
# Need to use wall time for this test due to the sleep calls
|
33
|
+
RubyProf::measure_mode = RubyProf::WALL_TIME
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_stack_can_be_printed
|
37
|
+
start_time = Time.now
|
38
|
+
RubyProf.start
|
39
|
+
5.times{STPT.new.a}
|
40
|
+
result = RubyProf.stop
|
41
|
+
end_time = Time.now
|
42
|
+
expected_time = end_time - start_time
|
43
|
+
|
44
|
+
file_contents = nil
|
45
|
+
assert_nothing_raised { file_contents = print(result) }
|
46
|
+
assert file_contents =~ /Thread: (\d+) \(100\.00% ~ ([.0-9]+)\)/
|
47
|
+
actual_time = $2.to_f
|
48
|
+
difference = (expected_time-actual_time).abs
|
49
|
+
assert difference<0.001 # less than 1 ms
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_method_elimination
|
53
|
+
RubyProf.start
|
54
|
+
5.times{STPT.new.a}
|
55
|
+
result = RubyProf.stop
|
56
|
+
assert_nothing_raised {
|
57
|
+
# result.dump
|
58
|
+
result.eliminate_methods!([/Integer#times/])
|
59
|
+
# $stderr.puts "================================"
|
60
|
+
# result.dump
|
61
|
+
print(result)
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
def print(result)
|
67
|
+
test = caller.first =~ /in `(.*)'/ ? $1 : "test"
|
68
|
+
testfile_name = "#{Dir::tmpdir}/ruby_prof_#{test}.html"
|
69
|
+
printer = RubyProf::CallStackPrinter.new(result)
|
70
|
+
File.open(testfile_name, "w") {|f| printer.print(f, :threshold => 0, :min_percent => 0, :title => "ruby_prof #{test}")}
|
71
|
+
system("open '#{testfile_name}'") if RUBY_PLATFORM =~ /darwin/ && ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT']=="1"
|
72
|
+
File.open(testfile_name, "r"){|f| f.read}
|
73
|
+
end
|
74
|
+
end
|
data/test/stack_test.rb
CHANGED
@@ -76,7 +76,7 @@ class StackTest < Test::Unit::TestCase
|
|
76
76
|
call_info = method.call_infos[0]
|
77
77
|
assert_equal('StackTest#test_call_sequence->StackClass#a', call_info.call_sequence)
|
78
78
|
assert_equal(3, call_info.children.length)
|
79
|
-
|
79
|
+
|
80
80
|
# Check Kernel#sleep
|
81
81
|
method = methods[2]
|
82
82
|
assert_equal('Kernel#sleep', method.full_name)
|
data/test/start_stop_test.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'test/unit'
|
4
4
|
require 'ruby-prof'
|
5
|
-
|
5
|
+
|
6
6
|
class StartStopTest < Test::Unit::TestCase
|
7
7
|
def setup
|
8
8
|
# Need to use wall time for this test due to the sleep calls
|
@@ -92,4 +92,4 @@ class StartStopTest < Test::Unit::TestCase
|
|
92
92
|
assert_equal('StartStopTest#method1->StartStopTest#method2->StartStopTest#method3->Kernel#sleep', call_info.call_sequence)
|
93
93
|
assert_equal(0, call_info.children.length)
|
94
94
|
end
|
95
|
-
end
|
95
|
+
end
|
data/test/test_suite.rb
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
begin
|
2
|
+
require 'rubygems'
|
3
|
+
require 'redgreen'
|
4
|
+
rescue LoadError
|
5
|
+
end
|
6
|
+
|
1
7
|
require 'test/unit'
|
2
8
|
|
3
9
|
require 'aggregate_test'
|
@@ -16,6 +22,9 @@ require 'stack_test'
|
|
16
22
|
require 'start_stop_test'
|
17
23
|
require 'thread_test'
|
18
24
|
require 'unique_call_path_test'
|
25
|
+
require 'stack_printer_test'
|
26
|
+
require 'multi_printer_test'
|
27
|
+
require 'method_elimination_test'
|
19
28
|
|
20
29
|
# Can't use this one here cause it breaks
|
21
30
|
# the rest of the unit tets (Ruby Prof gets
|
data/test/thread_test.rb
CHANGED
@@ -21,11 +21,11 @@ class ThreadTest < Test::Unit::TestCase
|
|
21
21
|
result = RubyProf.stop
|
22
22
|
assert_equal(2, result.threads.keys.length) # this should pass...
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
def test_thread_identity
|
26
26
|
RubyProf.start
|
27
27
|
thread = Thread.new do
|
28
|
-
sleep(1)
|
28
|
+
sleep(1)
|
29
29
|
end
|
30
30
|
thread.join
|
31
31
|
result = RubyProf.stop
|
@@ -36,16 +36,16 @@ class ThreadTest < Test::Unit::TestCase
|
|
36
36
|
|
37
37
|
assert(thread_ids.include?(threads[0].object_id))
|
38
38
|
assert(thread_ids.include?(threads[1].object_id))
|
39
|
-
|
39
|
+
|
40
40
|
assert_instance_of(Thread, ObjectSpace._id2ref(thread_ids[0]))
|
41
41
|
assert(threads.include?(ObjectSpace._id2ref(thread_ids[0])))
|
42
|
-
|
42
|
+
|
43
43
|
assert_instance_of(Thread, ObjectSpace._id2ref(thread_ids[1]))
|
44
44
|
assert(threads.include?(ObjectSpace._id2ref(thread_ids[1])))
|
45
45
|
end
|
46
46
|
|
47
47
|
def test_thread_timings
|
48
|
-
|
48
|
+
RubyProf.start
|
49
49
|
thread = Thread.new do
|
50
50
|
sleep 0 # force it to hit thread.join, below, first
|
51
51
|
# thus forcing sleep(1), below, to be counted as (wall) self_time
|
@@ -55,7 +55,7 @@ class ThreadTest < Test::Unit::TestCase
|
|
55
55
|
end
|
56
56
|
thread.join
|
57
57
|
result = RubyProf.stop
|
58
|
-
|
58
|
+
|
59
59
|
# Check background thread
|
60
60
|
assert_equal(2, result.threads.length)
|
61
61
|
methods = result.threads[thread.object_id].sort.reverse
|
@@ -96,7 +96,7 @@ class ThreadTest < Test::Unit::TestCase
|
|
96
96
|
# the sub calls to Object#new, when popped,
|
97
97
|
# cause the parent frame to be created for method #test_thread_timings, which means a +1 when it's popped in the end
|
98
98
|
# xxxx a test that shows it the other way, too (never creates parent frame--if that's even possible)
|
99
|
-
assert_equal(1, method.called)
|
99
|
+
assert_equal(1, method.called)
|
100
100
|
assert_in_delta(1, method.total_time, 0.01)
|
101
101
|
assert_in_delta(0, method.self_time, 0.05)
|
102
102
|
assert_in_delta(0, method.wait_time, 0.05)
|
@@ -111,7 +111,7 @@ class ThreadTest < Test::Unit::TestCase
|
|
111
111
|
assert_equal('Thread#join', method.full_name)
|
112
112
|
assert_equal(1, method.called)
|
113
113
|
assert_in_delta(1, method.total_time, 0.01)
|
114
|
-
assert_in_delta(0, method.self_time, 0.01)
|
114
|
+
assert_in_delta(0, method.self_time, 0.01)
|
115
115
|
assert_in_delta(1.0, method.wait_time, 0.01)
|
116
116
|
assert_in_delta(0, method.children_time, 0.01)
|
117
117
|
|
@@ -146,18 +146,18 @@ class ThreadTest < Test::Unit::TestCase
|
|
146
146
|
assert_equal('ThreadTest#test_thread_timings-><Class::Thread>#new->Thread#initialize', call_info.call_sequence)
|
147
147
|
assert_equal(0, call_info.children.length)
|
148
148
|
end
|
149
|
-
|
149
|
+
|
150
150
|
# useless test
|
151
151
|
def test_thread_back_and_forth
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
152
|
+
result = RubyProf.profile do
|
153
|
+
a = Thread.new { 100_000.times { sleep 0 }}
|
154
|
+
b = Thread.new { 100_000.times { sleep 0 }}
|
155
|
+
a.join
|
156
|
+
b.join
|
157
|
+
end
|
158
|
+
assert result.threads.values.flatten.sort[-1].total_time < 10 # 10s
|
159
159
|
end
|
160
|
-
|
160
|
+
|
161
161
|
def test_thread
|
162
162
|
result = RubyProf.profile do
|
163
163
|
begin
|
@@ -112,7 +112,7 @@ class UniqueCallPathTest < Test::Unit::TestCase
|
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
115
|
-
assert !call_info_a.nil?
|
115
|
+
assert !call_info_a.nil?
|
116
116
|
|
117
117
|
children_of_a = Array.new
|
118
118
|
|
@@ -121,7 +121,7 @@ class UniqueCallPathTest < Test::Unit::TestCase
|
|
121
121
|
children_of_a.push(c)
|
122
122
|
end
|
123
123
|
end
|
124
|
-
|
124
|
+
|
125
125
|
if RUBY_VERSION < '1.9'
|
126
126
|
assert_equal(4, call_info_a.target.children.length)
|
127
127
|
else
|
@@ -139,7 +139,7 @@ class UniqueCallPathTest < Test::Unit::TestCase
|
|
139
139
|
assert_equal(1, children_of_a.length)
|
140
140
|
assert_equal("UniqueCallPath#method_b", children_of_a[0].target.full_name)
|
141
141
|
end
|
142
|
-
|
142
|
+
|
143
143
|
end
|
144
144
|
|
145
145
|
def test_id2ref
|
@@ -222,4 +222,4 @@ class UniqueCallPathTest < Test::Unit::TestCase
|
|
222
222
|
assert_equal("UniqueCallPath#method_b", children_of_a[0].target.full_name)
|
223
223
|
end
|
224
224
|
end
|
225
|
-
end
|
225
|
+
end
|
metadata
CHANGED
@@ -5,17 +5,17 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 9
|
9
|
+
- 0
|
10
|
+
version: 0.9.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
|
-
- Shugo Maeda, Charlie Savage, Roger Pack
|
13
|
+
- Shugo Maeda, Charlie Savage, Roger Pack, Stefan Kaes
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-08-11 00:00:00 -06:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -50,11 +50,11 @@ description: |
|
|
50
50
|
ruby-prof is a fast code profiler for Ruby. It is a C extension and
|
51
51
|
therefore is many times faster than the standard Ruby profiler. It
|
52
52
|
supports both flat and graph profiles. For each method, graph profiles
|
53
|
-
show how long the method ran, which methods called it and which
|
53
|
+
show how long the method ran, which methods called it and which
|
54
54
|
methods it called. RubyProf generate both text and html and can output
|
55
55
|
it to standard out or to a file.
|
56
56
|
|
57
|
-
email: shugo@ruby-lang.org, cfis@savagexi.com, rogerdpack@gmail.com
|
57
|
+
email: shugo@ruby-lang.org, cfis@savagexi.com, rogerdpack@gmail.com, skaes@railsexpress.de
|
58
58
|
executables:
|
59
59
|
- ruby-prof
|
60
60
|
extensions:
|
@@ -63,13 +63,23 @@ extra_rdoc_files: []
|
|
63
63
|
|
64
64
|
files:
|
65
65
|
- Rakefile
|
66
|
-
- README
|
66
|
+
- README.rdoc
|
67
67
|
- LICENSE
|
68
68
|
- CHANGES
|
69
69
|
- bin/ruby-prof
|
70
|
+
- examples/empty.png
|
70
71
|
- examples/flat.txt
|
72
|
+
- examples/graph.dot
|
71
73
|
- examples/graph.html
|
74
|
+
- examples/graph.png
|
72
75
|
- examples/graph.txt
|
76
|
+
- examples/minus.png
|
77
|
+
- examples/multi.flat.txt
|
78
|
+
- examples/multi.graph.html
|
79
|
+
- examples/multi.grind.dat
|
80
|
+
- examples/multi.stack.html
|
81
|
+
- examples/plus.png
|
82
|
+
- examples/stack.html
|
73
83
|
- ext/ruby_prof/ruby_prof.c
|
74
84
|
- ext/ruby_prof/measure_allocations.h
|
75
85
|
- ext/ruby_prof/measure_cpu_time.h
|
@@ -85,12 +95,20 @@ files:
|
|
85
95
|
- lib/ruby-prof/abstract_printer.rb
|
86
96
|
- lib/ruby-prof/aggregate_call_info.rb
|
87
97
|
- lib/ruby-prof/call_info.rb
|
98
|
+
- lib/ruby-prof/call_stack_printer.rb
|
88
99
|
- lib/ruby-prof/call_tree_printer.rb
|
100
|
+
- lib/ruby-prof/dot_printer.rb
|
101
|
+
- lib/ruby-prof/empty.png
|
89
102
|
- lib/ruby-prof/flat_printer.rb
|
90
103
|
- lib/ruby-prof/flat_printer_with_line_numbers.rb
|
91
104
|
- lib/ruby-prof/graph_html_printer.rb
|
92
105
|
- lib/ruby-prof/graph_printer.rb
|
93
106
|
- lib/ruby-prof/method_info.rb
|
107
|
+
- lib/ruby-prof/minus.png
|
108
|
+
- lib/ruby-prof/multi_printer.rb
|
109
|
+
- lib/ruby-prof/plus.png
|
110
|
+
- lib/ruby-prof/rack.rb
|
111
|
+
- lib/ruby-prof/result.rb
|
94
112
|
- lib/ruby-prof/symbol_to_proc.rb
|
95
113
|
- lib/ruby-prof/task.rb
|
96
114
|
- lib/ruby-prof/test.rb
|
@@ -111,7 +129,9 @@ files:
|
|
111
129
|
- test/exec_test.rb
|
112
130
|
- test/line_number_test.rb
|
113
131
|
- test/measurement_test.rb
|
132
|
+
- test/method_elimination_test.rb
|
114
133
|
- test/module_test.rb
|
134
|
+
- test/multi_printer_test.rb
|
115
135
|
- test/no_method_class_test.rb
|
116
136
|
- test/prime.rb
|
117
137
|
- test/prime_test.rb
|
@@ -119,6 +139,7 @@ files:
|
|
119
139
|
- test/recursive_test.rb
|
120
140
|
- test/ruby-prof-bin
|
121
141
|
- test/singleton_test.rb
|
142
|
+
- test/stack_printer_test.rb
|
122
143
|
- test/stack_test.rb
|
123
144
|
- test/start_stop_test.rb
|
124
145
|
- test/test_suite.rb
|