ruby-prof 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/CHANGES +30 -0
  2. data/README +65 -25
  3. data/Rakefile +33 -32
  4. data/bin/ruby-prof +100 -83
  5. data/examples/graph.html +65 -69
  6. data/ext/measure_allocations.h +43 -0
  7. data/ext/measure_cpu_time.h +138 -0
  8. data/ext/measure_process_time.h +41 -0
  9. data/ext/measure_wall_time.h +42 -0
  10. data/ext/ruby_prof.c +737 -653
  11. data/lib/ruby-prof.rb +41 -38
  12. data/lib/ruby-prof/abstract_printer.rb +42 -0
  13. data/lib/ruby-prof/call_tree_printer.rb +69 -0
  14. data/lib/ruby-prof/flat_printer.rb +78 -75
  15. data/lib/ruby-prof/graph_html_printer.rb +241 -228
  16. data/lib/ruby-prof/graph_printer.rb +160 -141
  17. data/lib/ruby-prof/profile_test_case.rb +80 -0
  18. data/lib/ruby-prof/rails_plugin/ruby-prof/init.rb +6 -0
  19. data/lib/ruby-prof/rails_plugin/ruby-prof/lib/profiling.rb +52 -0
  20. data/lib/ruby-prof/task.rb +147 -0
  21. data/test/basic_test.rb +65 -35
  22. data/test/duplicate_names_test.rb +20 -24
  23. data/test/gc.log +5 -0
  24. data/test/measure_mode_test.rb +79 -0
  25. data/test/module_test.rb +31 -18
  26. data/test/no_method_class_test.rb +14 -0
  27. data/test/prime1.rb +17 -0
  28. data/test/prime2.rb +26 -0
  29. data/test/prime3.rb +17 -0
  30. data/test/prime_test.rb +10 -10
  31. data/test/printers_test.rb +14 -12
  32. data/test/profile_unit_test.rb +24 -0
  33. data/test/recursive_test.rb +105 -17
  34. data/test/singleton_test.rb +38 -0
  35. data/test/start_test.rb +24 -0
  36. data/test/test_helper.rb +33 -29
  37. data/test/test_suite.rb +10 -2
  38. data/test/thread_test.rb +123 -17
  39. data/test/timing_test.rb +70 -29
  40. metadata +28 -30
  41. data/doc/created.rid +0 -1
  42. data/doc/files/LICENSE.html +0 -0
  43. data/doc/files/README.html +0 -376
  44. data/doc/files/bin/ruby-prof.html +0 -143
  45. data/doc/files/examples/flat_txt.html +0 -179
  46. data/doc/files/examples/graph_html.html +0 -948
  47. data/doc/files/examples/graph_txt.html +0 -297
  48. data/doc/files/ext/ruby_prof_c.html +0 -101
  49. data/doc/files/lib/ruby-prof/flat_printer_rb.html +0 -101
  50. data/doc/files/lib/ruby-prof/graph_html_printer_rb.html +0 -108
  51. data/doc/files/lib/ruby-prof/graph_printer_rb.html +0 -101
  52. data/doc/files/lib/ruby-prof/profiletask_rb.html +0 -109
  53. data/doc/files/lib/ruby-prof_rb.html +0 -111
  54. data/doc/files/lib/unprof_rb.html +0 -108
  55. data/doc/rdoc-style.css +0 -208
  56. data/lib/ruby-prof/profiletask.rb +0 -150
  57. data/test/clock_mode_test.rb +0 -73
@@ -4,16 +4,22 @@ require 'test/unit'
4
4
  require 'ruby-prof'
5
5
  require 'test_helper'
6
6
 
7
+ # Need to use wall time for this test due to the sleep calls
8
+ RubyProf::measure_mode = RubyProf::WALL_TIME
9
+
7
10
  class C1
8
11
  def C1.hello
12
+ sleep(0.1)
9
13
  end
10
14
 
11
15
  def hello
16
+ sleep(0.2)
12
17
  end
13
18
  end
14
19
 
15
20
  module M1
16
21
  def hello
22
+ sleep(0.3)
17
23
  end
18
24
  end
19
25
 
@@ -24,11 +30,13 @@ end
24
30
 
25
31
  class C3
26
32
  def hello
33
+ sleep(0.4)
27
34
  end
28
35
  end
29
36
 
30
37
  module M4
31
38
  def hello
39
+ sleep(0.5)
32
40
  end
33
41
  end
34
42
 
@@ -58,7 +66,7 @@ class BasicTest < Test::Unit::TestCase
58
66
  def test_double_profile
59
67
  RubyProf.start
60
68
  assert_raise(RuntimeError) do
61
- RubyProf.start
69
+ RubyProf.start
62
70
  end
63
71
 
64
72
  assert_raise(RuntimeError) do
@@ -71,68 +79,79 @@ class BasicTest < Test::Unit::TestCase
71
79
 
72
80
  def test_no_block
73
81
  assert_raise(ArgumentError) do
74
- RubyProf.profile
75
- end
82
+ RubyProf.profile
83
+ end
76
84
  end
77
85
 
78
86
  def test_class_and_instance_methods
79
87
  result = RubyProf.profile do
80
- C1.hello
81
- C1.new.hello
88
+ C1.hello
89
+ C1.new.hello
82
90
  end
83
-
91
+
84
92
  methods = result.threads.values.first
85
93
 
86
94
  # Length should be 6:
87
- # 1 top level,
88
- # 1 Class.new
89
- # 1 Class:Object allocate
95
+ # 1 test_class_and_instance_methods (this method)
96
+ # 1 Class.new
97
+ # 1 Class:Object allocate
90
98
  # 1 for Object.initialize
91
99
  # 1 for Class hello
92
100
  # 1 for Object hello
93
- assert_equal(6, methods.length)
101
+ # 1 sleep
102
+ assert_equal(7, methods.length)
94
103
 
95
- # Check class method
96
- method1 = methods['<Class::C1>#hello']
97
- assert_not_nil(method1)
104
+ # Check the names
105
+ methods = methods.sort.reverse
98
106
 
99
- # Check instance method
100
- method1 = methods['C1#hello']
101
- assert_not_nil(method1)
107
+ assert_equal('BasicTest#test_class_and_instance_methods', methods[0].full_name)
108
+ assert_equal('Kernel#sleep', methods[1].full_name)
109
+ assert_equal('C1#hello', methods[2].full_name)
110
+ assert_equal('<Class::C1>#hello', methods[3].full_name)
111
+ assert_equal('Class#new', methods[4].full_name)
112
+ assert_equal('<Class::Object>#allocate', methods[5].full_name)
113
+ assert_equal('Object#initialize', methods[6].full_name)
102
114
  end
103
115
 
104
116
  def test_module_methods
105
117
  result = RubyProf.profile do
106
- C2.hello
107
- C2.new.hello
118
+ C2.hello
119
+ C2.new.hello
108
120
  end
109
121
 
110
122
  methods = result.threads.values.first
111
123
 
112
- # Length should be 5:
113
- # 1 top level,
114
- # 1 Class.new
115
- # 1 Class:Object allocate
116
- # 1 for Object.initialize
117
- # 1 for hello
118
- assert_equal(5, methods.length)
124
+ # Length should be 6:
125
+ # 1 BasicTest#test_module_methods (this method)
126
+ # 1 Class#new
127
+ # 1 <Class::Object>#allocate
128
+ # 1 Object#initialize
129
+ # 1 M1#hello
130
+ # 1 Kernel#sleep
131
+
132
+ assert_equal(6, methods.length)
133
+
134
+ # Check the names
135
+ methods = methods.sort.reverse
119
136
 
120
- # Check class method
121
- method1 = methods['M1#hello']
122
- assert_not_nil(method1)
123
- assert_equal(2, method1.called)
137
+ assert_equal('BasicTest#test_module_methods', methods[0].full_name)
138
+ assert_equal('M1#hello', methods[1].full_name)
139
+ assert_equal('Kernel#sleep', methods[2].full_name)
140
+ assert_equal('Class#new', methods[3].full_name)
141
+ assert_equal('<Class::Object>#allocate', methods[4].full_name)
142
+ assert_equal('Object#initialize', methods[5].full_name)
124
143
  end
125
144
 
126
145
  def test_singleton
127
146
  c3 = C3.new
128
147
 
129
148
  class << c3
130
- def hello
131
- end
132
- end
149
+ def hello
150
+ end
151
+ end
133
152
 
134
153
  result = RubyProf.profile do
135
- c3.hello
154
+ c3.hello
136
155
  end
137
156
 
138
157
  methods = result.threads.values.first
@@ -142,7 +161,18 @@ class BasicTest < Test::Unit::TestCase
142
161
  assert_equal(2, methods.length)
143
162
 
144
163
  # Check singleton method
145
- method1 = methods['<Object::C3>#hello']
146
- assert_not_nil(method1)
164
+ methods = methods.sort.reverse
165
+
166
+ assert_equal('BasicTest#test_singleton', methods[0].full_name)
167
+ assert_equal('<Object::C3>#hello', methods[1].full_name)
147
168
  end
169
+
170
+ def test_traceback
171
+ RubyProf.start
172
+ assert_raise(NoMethodError) do
173
+ RubyProf.xxx
174
+ end
175
+
176
+ RubyProf.stop
177
+ end
148
178
  end
@@ -7,31 +7,27 @@ require 'test_helper'
7
7
  class DuplicateNames < Test::Unit::TestCase
8
8
  def test_names
9
9
  result = RubyProf::profile do
10
- str = %{module Foo; class Bar; def foo; end end end}
10
+ str = %{module Foo; class Bar; def foo; end end end}
11
11
 
12
- eval str
13
- Foo::Bar.new.foo
14
- DuplicateNames.class_eval {remove_const :Foo}
12
+ eval str
13
+ Foo::Bar.new.foo
14
+ DuplicateNames.class_eval {remove_const :Foo}
15
15
 
16
- eval str
17
- Foo::Bar.new.foo
18
- DuplicateNames.class_eval {remove_const :Foo}
16
+ eval str
17
+ Foo::Bar.new.foo
18
+ DuplicateNames.class_eval {remove_const :Foo}
19
19
 
20
- eval str
21
- Foo::Bar.new.foo
22
- end
23
- print_results(result)
24
-
25
- # There should be 3 foo methods
26
- methods = result.threads.values.first
27
-
28
- method_info = methods['DuplicateNames::Foo::Bar#foo']
29
- assert_not_nil(method_info)
30
-
31
- method_info = methods['DuplicateNames::Foo::Bar#foo_1']
32
- assert_not_nil(method_info)
33
-
34
- method_info = methods['DuplicateNames::Foo::Bar#foo_2']
35
- assert_not_nil(method_info)
36
- end
20
+ eval str
21
+ Foo::Bar.new.foo
22
+ end
23
+
24
+ # There should be 3 foo methods
25
+ methods = result.threads.values.first
26
+
27
+ methods = methods.select do |method|
28
+ method.full_name == 'DuplicateNames::Foo::Bar#foo'
29
+ end
30
+
31
+ assert_equal(3, methods.length)
32
+ end
37
33
  end
@@ -0,0 +1,5 @@
1
+ GC Warning: Finalization cycle involving 99c25f0
2
+ GC Warning: Finalization cycle involving 99c25f0
3
+ GC Warning: Finalization cycle involving 99c25f0
4
+ GC Warning: Finalization cycle involving 99c25f0
5
+ GC Warning: Finalization cycle involving 99c25f0
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'ruby-prof'
5
+ require 'test_helper'
6
+ require 'prime'
7
+
8
+
9
+ # -- Tests ----
10
+ class MeasureModeTest < Test::Unit::TestCase
11
+
12
+ def test_process_time
13
+ RubyProf::measure_mode = RubyProf::PROCESS_TIME
14
+ assert_equal(RubyProf::PROCESS_TIME, RubyProf::measure_mode)
15
+ result = RubyProf.profile do
16
+ run_primes
17
+ end
18
+
19
+ result.threads.each do |thread_id, methods|
20
+ methods.each do |method|
21
+ check_parent_times(method)
22
+ check_parent_calls(method)
23
+ check_child_times(method)
24
+ end
25
+ end
26
+ end
27
+
28
+ def test_wall_time
29
+ RubyProf::measure_mode = RubyProf::WALL_TIME
30
+ assert_equal(RubyProf::WALL_TIME, RubyProf::measure_mode)
31
+ result = RubyProf.profile do
32
+ run_primes
33
+ end
34
+
35
+ result.threads.values.each do |methods|
36
+ methods.each do |method|
37
+ check_parent_times(method)
38
+ check_parent_calls(method)
39
+ check_child_times(method)
40
+ end
41
+ end
42
+ end
43
+
44
+ def test_cpu
45
+ return unless RubyProf.constants.include?('CPU_TIME')
46
+
47
+ RubyProf::measure_mode = RubyProf::CPU_TIME
48
+ assert_equal(RubyProf::CPU_TIME, RubyProf::measure_mode)
49
+ result = RubyProf.profile do
50
+ run_primes
51
+ end
52
+
53
+ result.threads.values.each do |methods|
54
+ methods.each do |method|
55
+ check_parent_times(method)
56
+ check_parent_calls(method)
57
+ check_child_times(method)
58
+ end
59
+ end
60
+ end
61
+
62
+ def test_allocated_objects
63
+ return unless RubyProf.constants.include?('ALLOCATIONS')
64
+
65
+ RubyProf::measure_mode = RubyProf::ALLOCATIONS
66
+
67
+ assert_equal(RubyProf::ALLOCATIONS, RubyProf::measure_mode)
68
+
69
+ result = RubyProf.profile do
70
+ Array.new
71
+ end
72
+ end
73
+
74
+ def test_invalid
75
+ assert_raise(ArgumentError) do
76
+ RubyProf::measure_mode = 7777
77
+ end
78
+ end
79
+ end
@@ -4,42 +4,55 @@ require 'test/unit'
4
4
  require 'ruby-prof'
5
5
  require 'test_helper'
6
6
 
7
+ # Need to use wall time for this test due to the sleep calls
8
+ RubyProf::measure_mode = RubyProf::WALL_TIME
9
+
7
10
 
8
11
  module Foo
9
12
  def Foo::hello
13
+ sleep(0.5)
10
14
  end
11
15
  end
12
16
 
13
17
  module Bar
14
18
  def Bar::hello
19
+ sleep(0.5)
15
20
  Foo::hello
16
21
  end
17
22
 
18
23
  def hello
24
+ sleep(0.5)
19
25
  Bar::hello
20
26
  end
21
27
  end
22
28
 
23
29
  include Bar
24
30
 
25
- class BasicTest < Test::Unit::TestCase
31
+ class ModuleTest < Test::Unit::TestCase
26
32
  def test_nested_modules
27
- result = RubyProf.profile do
28
- hello
29
- end
30
-
31
- methods = result.threads.values.first
32
-
33
- # Length should be 4s
34
- assert_equal(4, methods.length)
33
+ result = RubyProf.profile do
34
+ hello
35
+ end
36
+
37
+ methods = result.threads.values.first
38
+ methods = methods.sort.reverse
39
+
40
+ # Length should be 4
41
+ assert_equal(5, methods.length)
42
+
43
+ method = methods[0]
44
+ assert_equal('ModuleTest#test_nested_modules', method.full_name)
45
+
46
+ method = methods[1]
47
+ assert_equal('Bar#hello', method.full_name)
48
+
49
+ method = methods[2]
50
+ assert_equal('Kernel#sleep', method.full_name)
51
+
52
+ method = methods[3]
53
+ assert_equal('<Module::Bar>#hello', method.full_name)
35
54
 
36
- method1 = methods['Bar#hello']
37
- assert_not_nil(method1)
38
-
39
- method1 = methods['<Module::Bar>#hello']
40
- assert_not_nil(method1)
41
-
42
- method1 = methods['<Module::Foo>#hello']
43
- assert_not_nil(method1)
44
- end
55
+ method = methods[4]
56
+ assert_equal('<Module::Foo>#hello', method.full_name)
57
+ end
45
58
  end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'ruby-prof'
4
+
5
+ # Make sure this works with no class or method
6
+ result = RubyProf.profile do
7
+ sleep 1
8
+ end
9
+
10
+ method = result.threads.values.first.sort.last
11
+
12
+ if method.full_name != 'Global#[No method]'
13
+ raise(RuntimeError, "Wrong method name. Expected: Global#[No method]. Actual: #{method.full_name}")
14
+ end
@@ -0,0 +1,17 @@
1
+ require 'prime2'
2
+ require 'prime3'
3
+
4
+ def run_primes
5
+ length = 500
6
+ maxnum = 10000
7
+
8
+ # Create random numbers
9
+ random_array = make_random_array(length, maxnum)
10
+
11
+ # Find the primes
12
+ primes = find_primes(random_array)
13
+
14
+ # Find the largest primes
15
+ largest = find_largest(primes)
16
+ #puts "largest is #{largest}"
17
+ end
@@ -0,0 +1,26 @@
1
+ require 'prime3'
2
+
3
+ # Need to use wall time for this test due to the sleep calls
4
+ RubyProf::measure_mode = RubyProf::WALL_TIME
5
+
6
+ def find_primes(arr)
7
+ result = arr.select do |value|
8
+ is_prime(value)
9
+ end
10
+ result
11
+ end
12
+
13
+ def find_largest(primes)
14
+ largest = primes.first
15
+
16
+ # Intentionally use upto for example purposes
17
+ # (upto is also called from is_prime)
18
+ 0.upto(primes.length-1) do |i|
19
+ sleep(0.02)
20
+ prime = primes[i]
21
+ if prime > largest
22
+ largest = prime
23
+ end
24
+ end
25
+ largest
26
+ end