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
@@ -0,0 +1,17 @@
1
+
2
+ def make_random_array(length, maxnum)
3
+ result = Array.new(length)
4
+ result.each_index do |i|
5
+ result[i] = rand(maxnum)
6
+ end
7
+
8
+ result
9
+ end
10
+
11
+ def is_prime(x)
12
+ y = 2
13
+ y.upto(x-1) do |i|
14
+ return false if (x % i) == 0
15
+ end
16
+ true
17
+ end
@@ -10,15 +10,15 @@ require 'test_helper'
10
10
  class PrimeTest < Test::Unit::TestCase
11
11
  def test_consistency
12
12
  result = RubyProf.profile do
13
- run_primes
14
- end
15
-
16
- result.threads.values.each do |methods|
17
- methods.values.each do |method|
18
- check_parent_times(method)
19
- check_parent_calls(method)
20
- check_child_times(method)
21
- end
22
- end
13
+ run_primes
14
+ end
15
+
16
+ result.threads.values.each do |methods|
17
+ methods.each do |method|
18
+ check_parent_times(method)
19
+ check_parent_calls(method)
20
+ check_child_times(method)
21
+ end
22
+ end
23
23
  end
24
24
  end
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
-
3
2
  require 'test/unit'
4
3
  require 'ruby-prof'
5
4
  require 'prime'
@@ -8,21 +7,24 @@ require 'test_helper'
8
7
 
9
8
  # -- Tests ----
10
9
  class PrintersTest < Test::Unit::TestCase
11
- def test_printer
10
+ def test_printers
12
11
  result = RubyProf.profile do
13
- run_primes
14
- end
12
+ run_primes
13
+ end
15
14
 
16
- printer = RubyProf::FlatPrinter.new(result)
17
- printer.print(STDOUT)
18
-
19
- printer = RubyProf::GraphHtmlPrinter.new(result)
20
- printer.print(STDOUT)
21
-
22
- printer = RubyProf::GraphPrinter.new(result)
15
+ printer = RubyProf::FlatPrinter.new(result)
23
16
  printer.print(STDOUT)
24
17
 
18
+ printer = RubyProf::GraphHtmlPrinter.new(result)
19
+ printer.print
20
+
21
+ printer = RubyProf::GraphPrinter.new(result)
22
+ printer.print
23
+
24
+ printer = RubyProf::CallTreePrinter.new(result)
25
+ printer.print(STDOUT)
26
+
25
27
  # we should get here
26
28
  assert(true)
27
29
  end
28
- end
30
+ end
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'ruby-prof'
5
+ require 'test_helper'
6
+ require 'ruby-prof/profile_test_case'
7
+
8
+ # Need to use wall time for this test due to the sleep calls
9
+ RubyProf::measure_mode = RubyProf::WALL_TIME
10
+
11
+ # -- Tests ----
12
+ class ProfileTest < Test::Unit::TestCase
13
+ def test_profile
14
+ sleep(2)
15
+ end
16
+
17
+ def teardown
18
+ profile_dir = output_directory
19
+ assert(File.exists?(profile_dir))
20
+
21
+ file_path = File.join(profile_dir, 'test_profile_profile_test.html')
22
+ assert(File.exists?(file_path))
23
+ end
24
+ end
@@ -2,9 +2,10 @@
2
2
 
3
3
  require 'test/unit'
4
4
  require 'ruby-prof'
5
- require 'timeout'
6
5
  require 'test_helper'
7
6
 
7
+ # Need to use wall time for this test due to the sleep calls
8
+ RubyProf::measure_mode = RubyProf::WALL_TIME
8
9
 
9
10
  def simple(n)
10
11
  sleep(1)
@@ -13,6 +14,17 @@ def simple(n)
13
14
  simple(n)
14
15
  end
15
16
 
17
+ def cycle(n)
18
+ sub_cycle(n)
19
+ end
20
+
21
+ def sub_cycle(n)
22
+ sleep(1)
23
+ n -= 1
24
+ return if n == 0
25
+ cycle(n)
26
+ end
27
+
16
28
  def factorial(n)
17
29
  if n < 2 then
18
30
  n
@@ -24,18 +36,94 @@ end
24
36
 
25
37
  # -- Tests ----
26
38
  class RecursiveTest < Test::Unit::TestCase
27
- def test_recursive
39
+ def test_recursive
28
40
  result = RubyProf.profile do
29
- simple(3)
41
+ simple(2)
42
+ end
43
+
44
+ result.threads.values.each do |methods|
45
+ methods.each do |method|
46
+ check_parent_times(method)
47
+ check_parent_calls(method)
48
+ check_child_times(method)
49
+ end
50
+ end
51
+
52
+ methods = result.threads.values.first.sort.reverse
53
+ assert_equal(6, methods.length)
54
+
55
+ method = methods[0]
56
+ assert_equal('RecursiveTest#test_recursive', method.full_name)
57
+ assert_in_delta(2, method.total_time, 0.02)
58
+ assert_in_delta(0, method.self_time, 0.02)
59
+ assert_in_delta(0, method.wait_time, 0.02)
60
+ assert_in_delta(2, method.children_time, 0.02)
61
+ assert_equal(0, method.called)
62
+ assert_equal(0, method.parents.length)
63
+ assert_equal(1, method.children.length)
64
+
65
+ method = methods[1]
66
+ assert_equal('Object#simple', method.full_name)
67
+ assert_in_delta(2, method.total_time, 0.02)
68
+ assert_in_delta(0, method.self_time, 0.02)
69
+ assert_in_delta(0, method.wait_time, 0.02)
70
+ assert_in_delta(2, method.children_time, 0.02)
71
+ assert_equal(1, method.called)
72
+ assert_equal(1, method.parents.length)
73
+ assert_equal(4, method.children.length)
74
+
75
+ method = methods[2]
76
+ assert_equal('Kernel#sleep', method.full_name)
77
+ assert_in_delta(2, method.total_time, 0.02)
78
+ assert_in_delta(2, method.self_time, 0.02)
79
+ assert_in_delta(0, method.wait_time, 0.02)
80
+ assert_in_delta(0, method.children_time, 0.02)
81
+ assert_equal(2, method.called)
82
+ assert_equal(2, method.parents.length)
83
+ assert_equal(0, method.children.length)
84
+
85
+ method = methods[3]
86
+ assert_equal('Object#simple-1', method.full_name)
87
+ assert_in_delta(1, method.total_time, 0.02)
88
+ assert_in_delta(0, method.self_time, 0.02)
89
+ assert_in_delta(0, method.wait_time, 0.02)
90
+ assert_in_delta(1, method.children_time, 0.02)
91
+ assert_equal(1, method.called)
92
+ assert_equal(1, method.parents.length)
93
+ assert_equal(3, method.children.length)
94
+
95
+ method = methods[4]
96
+ assert_equal('Fixnum#==', method.full_name)
97
+ assert_in_delta(0, method.total_time, 0.02)
98
+ assert_in_delta(0, method.self_time, 0.02)
99
+ assert_in_delta(0, method.wait_time, 0.02)
100
+ assert_in_delta(0, method.children_time, 0.02)
101
+ assert_equal(2, method.called)
102
+ assert_equal(2, method.parents.length)
103
+ assert_equal(0, method.children.length)
104
+
105
+ method = methods[5]
106
+ assert_equal('Fixnum#-', method.full_name)
107
+ assert_in_delta(0, method.total_time, 0.02)
108
+ assert_in_delta(0, method.self_time, 0.02)
109
+ assert_in_delta(0, method.wait_time, 0.02)
110
+ assert_in_delta(0, method.children_time, 0.02)
111
+ assert_equal(2, method.called)
112
+ assert_equal(2, method.parents.length)
113
+ assert_equal(0, method.children.length)
114
+ end
115
+
116
+ def test_cycle
117
+ result = RubyProf.profile do
118
+ cycle(2)
30
119
  end
31
-
32
120
  result.threads.values.each do |methods|
33
- methods.values.each do |method|
34
- check_parent_times(method)
35
- check_parent_calls(method)
36
- check_child_times(method)
37
- end
38
- end
121
+ methods.each do |method|
122
+ check_parent_times(method)
123
+ check_parent_calls(method)
124
+ check_child_times(method)
125
+ end
126
+ end
39
127
  end
40
128
 
41
129
  def test_factorial
@@ -45,11 +133,11 @@ class RecursiveTest < Test::Unit::TestCase
45
133
  end
46
134
 
47
135
  result.threads.values.each do |methods|
48
- methods.values.each do |method|
49
- check_parent_times(method)
50
- check_parent_calls(method)
51
- check_child_times(method)
52
- end
53
- end
54
- end
136
+ methods.each do |method|
137
+ check_parent_times(method)
138
+ check_parent_calls(method)
139
+ check_child_times(method)
140
+ end
141
+ end
142
+ end
55
143
  end
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'ruby-prof'
5
+ require 'timeout'
6
+
7
+ # -- Test for bug [#5657]
8
+ # http://rubyforge.org/tracker/index.php?func=detail&aid=5657&group_id=1814&atid=7060
9
+
10
+
11
+ class A
12
+ attr_accessor :as
13
+ def initialize
14
+ @as = []
15
+ class << @as
16
+ def <<(an_a)
17
+ super
18
+ end
19
+ end
20
+ end
21
+
22
+ def <<(an_a)
23
+ @as << an_a
24
+ end
25
+ end
26
+
27
+ class SingletonTest < Test::Unit::TestCase
28
+ def test_singleton
29
+ result = RubyProf.profile do
30
+ a = A.new
31
+ a << :first_thing
32
+ assert_equal(1, a.as.size)
33
+ end
34
+ printer = RubyProf::FlatPrinter.new(result)
35
+ printer.print(STDOUT)
36
+ end
37
+ end
38
+
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'ruby-prof'
5
+
6
+
7
+ def start
8
+ RubyProf.start
9
+ end
10
+
11
+ def wait_around
12
+ sleep(2)
13
+ end
14
+
15
+ def stop
16
+ RubyProf.stop
17
+ end
18
+
19
+ start
20
+ wait_around
21
+ result = stop
22
+
23
+ printer = RubyProf::FlatPrinter.new(result)
24
+ printer.print(STDOUT)
@@ -1,45 +1,49 @@
1
1
  def print_results(result)
2
- printer = RubyProf::FlatPrinter.new(result)
3
- printer.print(STDOUT)
2
+ printer = RubyProf::FlatPrinter.new(result)
3
+ printer.print(STDOUT)
4
4
 
5
- STDOUT << "\n" * 2
5
+ STDOUT << "\n" * 2
6
6
 
7
- printer = RubyProf::GraphPrinter.new(result)
8
- printer.print(STDOUT)
7
+ printer = RubyProf::GraphPrinter.new(result)
8
+ printer.print(STDOUT)
9
9
  end
10
10
 
11
11
  def check_parent_times(method)
12
- return if method.parents.length == 0
12
+ return if method.parents.length == 0
13
13
 
14
- parents_self_time = method.parents.values.inject(0) do |sum, call_info|
15
- sum + call_info.self_time
16
- end
17
- assert_in_delta(method.self_time, parents_self_time, 0.01, method.name)
14
+ parents_self_time = method.parents.inject(0) do |sum, call_info|
15
+ sum + call_info.self_time
16
+ end
17
+
18
+ assert_in_delta(method.self_time, parents_self_time, 0.01, method.full_name)
18
19
 
19
- parents_children_time = method.parents.values.inject(0) do |sum, call_info|
20
- sum + call_info.children_time
21
- end
22
- assert_in_delta(method.children_time, parents_children_time, 0.01, method.name)
20
+ parents_wait_time = method.parents.inject(0) do |sum, call_info|
21
+ sum + call_info.wait_time
22
+ end
23
+
24
+ assert_in_delta(method.wait_time, parents_wait_time, 0.01, method.full_name)
25
+
26
+ parents_children_time = method.parents.inject(0) do |sum, call_info|
27
+ sum + call_info.children_time
28
+ end
29
+ assert_in_delta(method.children_time, parents_children_time, 0.01, method.full_name)
23
30
  end
24
31
 
25
32
  def check_parent_calls(method)
26
- return if method.parents.length == 0
27
-
28
- parent_calls = method.parents.values.inject(0) do |sum, call_info|
29
- sum + call_info.called
30
- end
31
- assert_equal(method.called, parent_calls, method.name)
33
+ return if method.parents.length == 0
34
+
35
+ parent_calls = method.parents.inject(0) do |sum, call_info|
36
+ sum + call_info.called
37
+ end
38
+ assert_equal(method.called, parent_calls, method.full_name)
32
39
  end
33
40
 
34
41
  def check_child_times(method)
35
- return if method.children.length == 0
42
+ return if method.children.length == 0
36
43
 
37
- children_total_time = method.children.values.inject(0) do |sum, call_info|
38
- sum + call_info.total_time
39
- end
40
-
41
- assert_in_delta(method.children_time, children_total_time, 0.01, method.name)
42
- end
44
+ children_total_time = method.children.inject(0) do |sum, call_info|
45
+ sum + call_info.total_time
46
+ end
43
47
 
44
-
45
-
48
+ assert_in_delta(method.children_time, children_total_time, 0.01, method.full_name)
49
+ end
@@ -1,10 +1,18 @@
1
1
  # file ts_dbaccess.rb
2
2
  require 'test/unit'
3
3
  require 'basic_test'
4
- require 'module_test'
5
4
  require 'duplicate_names_test'
6
- require 'timing_test'
5
+ require 'measure_mode_test'
6
+ require 'module_test'
7
+ require 'no_method_class_test'
7
8
  require 'prime_test'
8
9
  require 'printers_test'
9
10
  require 'recursive_test'
11
+ require 'singleton_test'
10
12
  require 'thread_test'
13
+ require 'timing_test'
14
+
15
+ # Can't use this one here cause it breaks
16
+ # the rest of the unit tets (Ruby Prof gets
17
+ # started twice).
18
+ #require 'profile_unit_test'
@@ -5,28 +5,134 @@ require 'ruby-prof'
5
5
  require 'timeout'
6
6
  require 'test_helper'
7
7
 
8
+ # Need to use wall time for this test due to the sleep calls
9
+ RubyProf::measure_mode = RubyProf::WALL_TIME
10
+
8
11
  # -- Tests ----
9
12
  class ThreadTest < Test::Unit::TestCase
10
- def test_thread
13
+ def test_thread_timings
11
14
  RubyProf.start
12
15
 
13
- begin
14
- status = Timeout::timeout(2) do
15
- while true
16
- next
17
- end
18
- end
19
- rescue Timeout::Error
20
- end
21
-
16
+ sleep(2)
17
+
18
+ thread = Thread.new do
19
+ sleep(0.5)
20
+ sleep(2)
21
+ end
22
+
23
+ thread.join
24
+
22
25
  result = RubyProf.stop
26
+
27
+ values = result.threads.values.sort do |value1, value2|
28
+ value1.length <=> value2.length
29
+ end
30
+
31
+ # Check background thread
32
+ methods = values.first.sort.reverse
33
+ assert_equal(2, methods.length)
34
+
35
+ method = methods[0]
36
+ assert_equal('ThreadTest#test_thread_timings', method.full_name)
37
+ assert_in_delta(2.5, method.total_time, 0.02)
38
+ assert_in_delta(0, method.self_time, 0.02)
39
+ assert_in_delta(0.5, method.wait_time, 0.02)
40
+ assert_in_delta(2.0, method.children_time, 0.02)
41
+ assert_equal(0, method.called)
42
+ assert_equal(0, method.parents.length)
43
+ assert_equal(1, method.children.length)
44
+
45
+ method = methods[1]
46
+ assert_equal('Kernel#sleep', method.full_name)
47
+ assert_in_delta(2.5, method.total_time, 0.02)
48
+ assert_in_delta(2.0, method.self_time, 0.02)
49
+ assert_in_delta(0.5, method.wait_time, 0.02)
50
+ assert_in_delta(0, method.children_time, 0.02)
51
+ assert_equal(2, method.called)
52
+ assert_equal(1, method.parents.length)
53
+ assert_equal(0, method.children.length)
54
+
55
+ # Check foreground thread
56
+ methods = values.last.sort.reverse
57
+ assert_equal(5, methods.length)
58
+ methods = methods.sort.reverse
59
+
60
+ method = methods[0]
61
+ assert_equal('ThreadTest#test_thread_timings', method.full_name)
62
+ assert_in_delta(4.5, method.total_time, 0.02)
63
+ assert_in_delta(0, method.self_time, 0.02)
64
+ assert_in_delta(2.0, method.wait_time, 0.02)
65
+ assert_in_delta(2.5, method.children_time, 0.02)
66
+ assert_equal(0, method.called)
67
+ assert_equal(0, method.parents.length)
68
+ assert_equal(3, method.children.length)
69
+
70
+ method = methods[1]
71
+ assert_equal('Thread#join', method.full_name)
72
+ assert_in_delta(2.5, method.total_time, 0.02)
73
+ assert_in_delta(0.5, method.self_time, 0.02)
74
+ assert_in_delta(2.0, method.wait_time, 0.02)
75
+ assert_in_delta(0, method.children_time, 0.02)
76
+ assert_equal(1, method.called)
77
+ assert_equal(1, method.parents.length)
78
+ assert_equal(0, method.children.length)
79
+
80
+ method = methods[2]
81
+ assert_equal('Kernel#sleep', method.full_name)
82
+ assert_in_delta(2, method.total_time, 0.02)
83
+ assert_in_delta(2.0, method.self_time, 0.02)
84
+ assert_in_delta(0, method.wait_time, 0.02)
85
+ assert_in_delta(0, method.children_time, 0.02)
86
+ assert_equal(1, method.called)
87
+ assert_equal(1, method.parents.length)
88
+ assert_equal(0, method.children.length)
89
+
90
+
91
+ method = methods[3]
92
+ assert_equal('Thread#initialize', method.full_name)
93
+ assert_in_delta(0, method.total_time, 0.02)
94
+ assert_in_delta(0, method.self_time, 0.02)
95
+ assert_in_delta(0, method.wait_time, 0.02)
96
+ assert_in_delta(0, method.children_time, 0.02)
97
+ assert_equal(1, method.called)
98
+ assert_equal(1, method.parents.length)
99
+ assert_equal(0, method.children.length)
100
+
101
+ method = methods[4]
102
+ assert_equal('<Class::Thread>#new', method.full_name)
103
+ assert_in_delta(0, method.total_time, 0.02)
104
+ assert_in_delta(0, method.self_time, 0.02)
105
+ assert_in_delta(0, method.wait_time, 0.02)
106
+ assert_in_delta(0, method.children_time, 0.02)
107
+ assert_equal(1, method.called)
108
+ assert_equal(1, method.parents.length)
109
+ assert_equal(1, method.children.length)
110
+ end
111
+
112
+ def test_thread
113
+ result = RubyProf.profile do
114
+ begin
115
+ status = Timeout::timeout(2) do
116
+ while true
117
+ next
118
+ end
119
+ end
120
+ rescue Timeout::Error
121
+ end
122
+ end
123
+
124
+ printer = RubyProf::GraphHtmlPrinter.new(result)
125
+ File.open('c:/temp/test.html', 'w') do |file|
126
+ printer.print(file)
127
+ end
23
128
 
24
- result.threads.values.each do |methods|
25
- methods.values.each do |method|
26
- check_parent_times(method)
27
- check_parent_calls(method)
28
- check_child_times(method)
29
- end
30
- end
129
+ result.threads.each do |thread_id, methods|
130
+ STDOUT << "thread: " << thread_id << "\n"
131
+ methods.each do |method|
132
+ check_parent_times(method)
133
+ check_parent_calls(method)
134
+ check_child_times(method)
135
+ end
136
+ end
31
137
  end
32
138
  end