ruby-prof 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/ruby-prof.rb CHANGED
@@ -32,6 +32,8 @@ module RubyProf
32
32
  RubyProf.measure_mode = RubyProf::CPU_TIME
33
33
  when "allocations"
34
34
  RubyProf.measure_mode = RubyProf::ALLOCATIONS
35
+ when "memory"
36
+ RubyProf.measure_mode = RubyProf::MEMORY
35
37
  else
36
38
  RubyProf.measure_mode = RubyProf::PROCESS_TIME
37
39
  end
@@ -13,13 +13,20 @@ module RubyProf
13
13
  @output << "events: "
14
14
  case RubyProf.measure_mode
15
15
  when RubyProf::PROCESS_TIME
16
+ @value_scale = RubyProf::CLOCKS_PER_SEC;
16
17
  @output << 'process_time'
17
18
  when RubyProf::WALL_TIME
19
+ @value_scale = 1_000_000
18
20
  @output << 'wall_time'
19
- when RubyProf::CPU_TIME
21
+ when RubyProf.const_defined?(:CPU_TIME) && RubyProf::CPU_TIME
22
+ @value_scale = RubyProf.cpu_frequency
20
23
  @output << 'cpu_time'
21
- when RubyProf::ALLOCATIONS
24
+ when RubyProf.const_defined?(:ALLOCATIONS) && RubyProf::ALLOCATIONS
25
+ @value_scale = 1
22
26
  @output << 'allocations'
27
+ when RubyProf.const_defined?(:MEMORY) && RubyProf::MEMORY
28
+ @value_scale = 1
29
+ @output << 'memory'
23
30
  end
24
31
  @output << "\n\n"
25
32
 
@@ -28,12 +35,12 @@ module RubyProf
28
35
 
29
36
  def print_threads
30
37
  @result.threads.each do |thread_id, methods|
31
- print_methods(thread_id ,methods)
38
+ print_methods(thread_id, methods)
32
39
  end
33
40
  end
34
41
 
35
42
  def convert(value)
36
- (value * 1000).round
43
+ (value * @value_scale).round
37
44
  end
38
45
 
39
46
  def file(method)
@@ -0,0 +1,27 @@
1
+ ***************
2
+ *** 28,39 ****
3
+
4
+ def print_threads
5
+ @result.threads.each do |thread_id, methods|
6
+ - print_methods(thread_id ,methods)
7
+ end
8
+ end
9
+
10
+ def convert(value)
11
+ - (value * 1000).round
12
+ end
13
+
14
+ def file(method)
15
+ --- 32,43 ----
16
+
17
+ def print_threads
18
+ @result.threads.each do |thread_id, methods|
19
+ + print_methods(thread_id ,methods)
20
+ end
21
+ end
22
+
23
+ def convert(value)
24
+ + (value * @value_scale).round
25
+ end
26
+
27
+ def file(method)
@@ -49,8 +49,8 @@ module RubyProf
49
49
  m1.self_time <=> m2.self_time
50
50
  end.reverse
51
51
 
52
- @output << "Thread ID: " << thread_id << "\n"
53
- @output << "Total: " << total_time << "\n"
52
+ @output << "Thread ID: %d\n" % thread_id
53
+ @output << "Total: %0.6f\n" % total_time
54
54
  @output << "\n"
55
55
  @output << " %self total self wait child calls name\n"
56
56
 
@@ -63,14 +63,15 @@ module RubyProf
63
63
  #self_time_called = method.called > 0 ? method.self_time/method.called : 0
64
64
  #total_time_called = method.called > 0? method.total_time/method.called : 0
65
65
 
66
- @output.printf("%6.2f %8.2f %8.2f %8.2f %8.2f %8d %s\n",
66
+ @output << "%6.2f %8.2f %8.2f %8.2f %8.2f %8d %s\n" % [
67
67
  method.self_time / total_time * 100, # %self
68
68
  method.total_time, # total
69
69
  method.self_time, # self
70
70
  method.wait_time, # wait
71
71
  method.children_time, # children
72
72
  method.called, # calls
73
- method_name(method)) # name
73
+ method_name(method) # name
74
+ ]
74
75
  end
75
76
  end
76
77
  end
@@ -9,8 +9,8 @@ module RubyProf
9
9
  # [code to profile]
10
10
  # end
11
11
  #
12
- # printer = RubyProf::GraphHtmlPrinter.new(result, 5)
13
- # printer.print(STDOUT, 0)
12
+ # printer = RubyProf::GraphHtmlPrinter.new(result)
13
+ # printer.print(STDOUT, :min_percent=>0)
14
14
  #
15
15
  # The constructor takes two arguments. The first is
16
16
  # a RubyProf::Result object generated from a profiling
@@ -47,8 +47,11 @@ module RubyProf
47
47
  @output = output
48
48
  setup_options(options)
49
49
 
50
+ filename = options[:filename]
51
+ template = filename ? File.read(filename).untaint : (options[:template] || self.template)
50
52
  _erbout = @output
51
53
  erb = ERB.new(template, nil, nil)
54
+ erb.filename = filename
52
55
  @output << erb.result(binding)
53
56
  end
54
57
 
@@ -146,6 +149,11 @@ module RubyProf
146
149
  border-left: 1px solid #CCC;
147
150
  text-align: center;
148
151
  }
152
+
153
+ .method_name {
154
+ text-align: left;
155
+ max-width: 25em;
156
+ }
149
157
  </style>
150
158
  </head>
151
159
  <body>
@@ -178,17 +186,20 @@ module RubyProf
178
186
  <th><%= sprintf("%#{TIME_WIDTH}s", "Wait") %></th>
179
187
  <th><%= sprintf("%#{TIME_WIDTH+2}s", "Child") %></th>
180
188
  <th><%= sprintf("%#{CALL_WIDTH}s", "Calls") %></th>
181
- <th>Name</th>
189
+ <th class="method_name">Name</th>
182
190
  <th>Line</th>
183
191
  </tr>
184
192
 
185
- <% methods.sort.reverse_each do |method|
193
+ <% min_time = @options[:min_time] || (@options[:nonzero] ? 0.005 : nil)
194
+ methods.sort.reverse_each do |method|
186
195
  total_percentage = (method.total_time/total_time) * 100
187
196
  next if total_percentage < min_percent
197
+ next if min_time && method.total_time < min_time
188
198
  self_percentage = (method.self_time/total_time) * 100 %>
189
199
 
190
200
  <!-- Parents -->
191
- <% for caller in method.parents %>
201
+ <% for caller in method.parents %>
202
+ <% next if min_time && caller.total_time < min_time %>
192
203
  <tr>
193
204
  <td>&nbsp;</td>
194
205
  <td>&nbsp;</td>
@@ -198,8 +209,8 @@ module RubyProf
198
209
  <td><%= sprintf("%#{TIME_WIDTH}.2f", caller.children_time) %></td>
199
210
  <% called = "#{caller.called}/#{method.called}" %>
200
211
  <td><%= sprintf("%#{CALL_WIDTH}s", called) %></td>
201
- <td><%= create_link(thread_id, caller.target) %></td>
202
- <td><a href="file://<%= File.expand_path(caller.target.source_file) %>#line=<%= caller.line %>"><%= caller.line %></a></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>
203
214
  </tr>
204
215
  <% end %>
205
216
 
@@ -211,12 +222,13 @@ module RubyProf
211
222
  <td><%= sprintf("%#{TIME_WIDTH}.2f", method.wait_time) %></td>
212
223
  <td><%= sprintf("%#{TIME_WIDTH}.2f", method.children_time) %></td>
213
224
  <td><%= sprintf("%#{CALL_WIDTH}i", method.called) %></td>
214
- <td><a name="<%= method_href(thread_id, method) %>"><%= h method.full_name %></a></td>
215
- <td><a href="file://<%= File.expand_path(method.source_file) %>#line=<%= method.line %>"><%= method.line %></a></td>
225
+ <td class="method_name"><a name="<%= method_href(thread_id, method) %>"><%= h method.full_name %></a></td>
226
+ <td><a href="file://<%=h srcfile=File.expand_path(method.source_file) %>#line=<%= linenum=method.line %>" title="<%=h srcfile %>:<%= linenum %>"><%= method.line %></a></td>
216
227
  </tr>
217
228
 
218
229
  <!-- Children -->
219
- <% for callee in method.children %>
230
+ <% for callee in method.children %>
231
+ <% next if min_time && callee.total_time < min_time %>
220
232
  <tr>
221
233
  <td>&nbsp;</td>
222
234
  <td>&nbsp;</td>
@@ -226,12 +238,12 @@ module RubyProf
226
238
  <td><%= sprintf("%#{TIME_WIDTH}.2f", callee.children_time) %></td>
227
239
  <% called = "#{callee.called}/#{callee.target.called}" %>
228
240
  <td><%= sprintf("%#{CALL_WIDTH}s", called) %></td>
229
- <td><%= create_link(thread_id, callee.target) %></td>
230
- <td><a href="file://<%= File.expand_path(method.source_file) %>#line=<%= callee.line %>"><%= callee.line %></a></td>
241
+ <td class="method_name"><%= create_link(thread_id, callee.target) %></td>
242
+ <td><a href="file://<%=h srcfile=File.expand_path(method.source_file) %>#line=<%= linenum=callee.line %>" title="<%=h srcfile %>:<%= linenum %>"><%= callee.line %></a></td>
231
243
  </tr>
232
244
  <% end %>
233
245
  <!-- Create divider row -->
234
- <tr class="break"><td colspan="8"></td></tr>
246
+ <tr class="break"><td colspan="9"></td></tr>
235
247
  <% end %>
236
248
  </table>
237
249
  <% end %>
data/test/basic_test.rb CHANGED
@@ -88,10 +88,10 @@ class BasicTest < Test::Unit::TestCase
88
88
  C1.hello
89
89
  C1.new.hello
90
90
  end
91
-
91
+
92
92
  methods = result.threads.values.first
93
93
 
94
- # Length should be 6:
94
+ # Length should be 7:
95
95
  # 1 test_class_and_instance_methods (this method)
96
96
  # 1 Class.new
97
97
  # 1 Class:Object allocate
@@ -108,9 +108,15 @@ class BasicTest < Test::Unit::TestCase
108
108
  assert_equal('Kernel#sleep', methods[1].full_name)
109
109
  assert_equal('C1#hello', methods[2].full_name)
110
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)
111
+
112
+ # The last three methods have total times of zero
113
+ assert_equal(0, methods[4].total_time)
114
+ assert_equal(0, methods[5].total_time)
115
+ assert_equal(0, methods[6].total_time)
116
+
117
+ #assert_equal('Class#new', methods[4].full_name)
118
+ #assert_equal('<Class::Object>#allocate', methods[5].full_name)
119
+ #assert_equal('Object#initialize', methods[6].full_name)
114
120
  end
115
121
 
116
122
  def test_module_methods
@@ -128,7 +134,7 @@ class BasicTest < Test::Unit::TestCase
128
134
  # 1 Object#initialize
129
135
  # 1 M1#hello
130
136
  # 1 Kernel#sleep
131
-
137
+
132
138
  assert_equal(6, methods.length)
133
139
 
134
140
  # Check the names
@@ -137,9 +143,15 @@ class BasicTest < Test::Unit::TestCase
137
143
  assert_equal('BasicTest#test_module_methods', methods[0].full_name)
138
144
  assert_equal('Kernel#sleep', methods[1].full_name)
139
145
  assert_equal('M1#hello', methods[2].full_name)
140
- assert_equal('<Class::Object>#allocate', methods[3].full_name)
141
- assert_equal('Class#new', methods[4].full_name)
142
- assert_equal('Object#initialize', methods[5].full_name)
146
+
147
+ # The last three methods have times of zero
148
+ assert_equal(0, methods[3].total_time)
149
+ assert_equal(0, methods[4].total_time)
150
+ assert_equal(0, methods[5].total_time)
151
+
152
+ #assert_equal('<Class::Object>#allocate', methods[3].full_name)
153
+ #assert_equal('Class#new', methods[4].full_name)
154
+ #assert_equal('Object#initialize', methods[5].full_name)
143
155
  end
144
156
 
145
157
  def test_singleton
@@ -60,7 +60,7 @@ class MeasureModeTest < Test::Unit::TestCase
60
60
  end
61
61
 
62
62
  def test_allocated_objects
63
- return unless RubyProf.constants.include?('ALLOCATIONS')
63
+ return if RubyProf::ALLOCATIONS.nil?
64
64
 
65
65
  RubyProf::measure_mode = RubyProf::ALLOCATIONS
66
66
 
@@ -7,24 +7,68 @@ require 'test_helper'
7
7
 
8
8
  # -- Tests ----
9
9
  class PrintersTest < Test::Unit::TestCase
10
- def test_printers
11
- result = RubyProf.profile do
10
+
11
+ def setup
12
+ @result = RubyProf.profile do
12
13
  run_primes
13
14
  end
15
+ end
14
16
 
15
- printer = RubyProf::FlatPrinter.new(result)
17
+ def test_printers
18
+ printer = RubyProf::FlatPrinter.new(@result)
16
19
  printer.print(STDOUT)
17
20
 
18
- printer = RubyProf::GraphHtmlPrinter.new(result)
21
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
19
22
  printer.print
20
23
 
21
- printer = RubyProf::GraphPrinter.new(result)
24
+ printer = RubyProf::GraphPrinter.new(@result)
22
25
  printer.print
23
26
 
24
- printer = RubyProf::CallTreePrinter.new(result)
27
+ printer = RubyProf::CallTreePrinter.new(@result)
25
28
  printer.print(STDOUT)
26
29
 
27
30
  # we should get here
28
31
  assert(true)
29
32
  end
33
+
34
+ def test_flatprinter_duckfriendliness
35
+ output = ''
36
+
37
+ printer = RubyProf::FlatPrinter.new(@result)
38
+ assert_nothing_raised { printer.print( output ) }
39
+
40
+ assert_match( /Thread ID: \d+/i, output )
41
+ assert_match( /Total: \d+\.\d+/i, output )
42
+ assert_match( /Object#run_primes/i, output )
43
+ end
44
+
45
+ def test_graphhtmlprinter_duckfriendliness
46
+ output = ''
47
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
48
+ assert_nothing_raised { printer.print(output) }
49
+
50
+ assert_match( /DTD HTML 4\.01/i, output )
51
+ assert_match( %r{<th>Total Time</th>}i, output )
52
+ assert_match( /Object#run_primes/i, output )
53
+ end
54
+
55
+ def test_graphprinter_duckfriendliness
56
+ output = ''
57
+ printer = RubyProf::GraphPrinter.new(@result)
58
+ assert_nothing_raised { printer.print(output) }
59
+
60
+ assert_match( /Thread ID: \d+/i, output )
61
+ assert_match( /Total Time: \d+\.\d+/i, output )
62
+ assert_match( /Object#run_primes/i, output )
63
+ end
64
+
65
+ def test_calltreeprinter_duckfriendliness
66
+ output = ''
67
+ printer = RubyProf::CallTreePrinter.new(@result)
68
+ assert_nothing_raised { printer.print(output) }
69
+
70
+ assert_match(/fn=Object::find_primes/i, output)
71
+ assert_match(/events: process_time/i, output)
72
+ end
73
+
30
74
  end
@@ -49,6 +49,7 @@ class RecursiveTest < Test::Unit::TestCase
49
49
  end
50
50
  end
51
51
 
52
+
52
53
  methods = result.threads.values.first.sort.reverse
53
54
  assert_equal(6, methods.length)
54
55
 
@@ -93,7 +94,7 @@ class RecursiveTest < Test::Unit::TestCase
93
94
  assert_equal(3, method.children.length)
94
95
 
95
96
  method = methods[4]
96
- assert_equal('Fixnum#-', method.full_name)
97
+ assert_equal('Fixnum#==', method.full_name)
97
98
  assert_in_delta(0, method.total_time, 0.02)
98
99
  assert_in_delta(0, method.self_time, 0.02)
99
100
  assert_in_delta(0, method.wait_time, 0.02)
@@ -103,7 +104,7 @@ class RecursiveTest < Test::Unit::TestCase
103
104
  assert_equal(0, method.children.length)
104
105
 
105
106
  method = methods[5]
106
- assert_equal('Fixnum#==', method.full_name)
107
+ assert_equal('Fixnum#-', method.full_name)
107
108
  assert_in_delta(0, method.total_time, 0.02)
108
109
  assert_in_delta(0, method.self_time, 0.02)
109
110
  assert_in_delta(0, method.wait_time, 0.02)
data/test/test_helper.rb CHANGED
@@ -15,7 +15,8 @@ def check_parent_times(method)
15
15
  sum + call_info.self_time
16
16
  end
17
17
 
18
- assert_in_delta(method.self_time, parents_self_time, 0.01, method.full_name)
18
+ assert_in_delta(method.self_time, parents_self_time, 0.01,
19
+ "Invalid parent times for method #{method.full_name}")
19
20
 
20
21
  parents_wait_time = method.parents.inject(0) do |sum, call_info|
21
22
  sum + call_info.wait_time
@@ -26,7 +27,9 @@ def check_parent_times(method)
26
27
  parents_children_time = method.parents.inject(0) do |sum, call_info|
27
28
  sum + call_info.children_time
28
29
  end
29
- assert_in_delta(method.children_time, parents_children_time, 0.01, method.full_name)
30
+
31
+ assert_in_delta(method.children_time, parents_children_time, 0.01,
32
+ "Invalid child times for method #{method.full_name}")
30
33
  end
31
34
 
32
35
  def check_parent_calls(method)
@@ -35,7 +38,9 @@ def check_parent_calls(method)
35
38
  parent_calls = method.parents.inject(0) do |sum, call_info|
36
39
  sum + call_info.called
37
40
  end
38
- assert_equal(method.called, parent_calls, method.full_name)
41
+
42
+ assert_equal(method.called, parent_calls,
43
+ "Invalid parent calls for method #{method.full_name}")
39
44
  end
40
45
 
41
46
  def check_child_times(method)
@@ -45,5 +50,6 @@ def check_child_times(method)
45
50
  sum + call_info.total_time
46
51
  end
47
52
 
48
- assert_in_delta(method.children_time, children_total_time, 0.01, method.full_name)
53
+ assert_in_delta(method.children_time, children_total_time, 0.01,
54
+ "Invalid child time for method #{method.full_name}")
49
55
  end
data/test/thread_test.rb CHANGED
@@ -120,6 +120,9 @@ class ThreadTest < Test::Unit::TestCase
120
120
  end
121
121
  end
122
122
 
123
+ printer = RubyProf::GraphPrinter.new(result)
124
+ printer.print
125
+
123
126
  result.threads.each do |thread_id, methods|
124
127
  STDOUT << "thread: " << thread_id << "\n"
125
128
  methods.each do |method|
metadata CHANGED
@@ -1,33 +1,32 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.2
3
- specification_version: 1
4
2
  name: ruby-prof
5
3
  version: !ruby/object:Gem::Version
6
- version: 0.5.2
7
- date: 2007-07-19 14:02:03 -06:00
8
- summary: Fast Ruby profiler
9
- require_paths:
10
- - lib
11
- email: shugo@ruby-lang.org and cfis@savagexi.com
12
- homepage: http://rubyforge.org/projects/ruby-prof/
13
- rubyforge_project: ruby-prof
14
- description: ruby-prof is a fast code profiler for Ruby. It is a C extension and therefore is many times faster than the standard Ruby profiler. It supports both flat and graph profiles. For each method, graph profiles show how long the method ran, which methods called it and which methods it called. RubyProf generate both text and html and can output it to standard out or to a file.
15
- autorequire: ruby-prof
16
- default_executable:
17
- bindir: bin
18
- has_rdoc: true
19
- required_ruby_version: !ruby/object:Gem::Version::Requirement
20
- requirements:
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: 1.8.4
24
- version:
4
+ version: 0.6.0
25
5
  platform: ruby
26
- signing_key:
27
- cert_chain:
28
- post_install_message:
29
6
  authors:
30
7
  - Shugo Maeda and Charlie Savage
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-02-03 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: ruby-prof is a fast code profiler for Ruby. It is a C extension and therefore is many times faster than the standard Ruby profiler. It supports both flat and graph profiles. For each method, graph profiles show how long the method ran, which methods called it and which methods it called. RubyProf generate both text and html and can output it to standard out or to a file.
17
+ email: shugo@ruby-lang.org and cfis@savagexi.com
18
+ executables:
19
+ - ruby-prof
20
+ extensions:
21
+ - ext/extconf.rb
22
+ extra_rdoc_files:
23
+ - bin/ruby-prof
24
+ - ext/ruby_prof.c
25
+ - examples/flat.txt
26
+ - examples/graph.txt
27
+ - examples/graph.html
28
+ - README
29
+ - LICENSE
31
30
  files:
32
31
  - Rakefile
33
32
  - README
@@ -39,6 +38,7 @@ files:
39
38
  - lib/unprof.rb
40
39
  - lib/ruby-prof/abstract_printer.rb
41
40
  - lib/ruby-prof/call_tree_printer.rb
41
+ - lib/ruby-prof/call_tree_printer.rb.rej
42
42
  - lib/ruby-prof/flat_printer.rb
43
43
  - lib/ruby-prof/graph_html_printer.rb
44
44
  - lib/ruby-prof/graph_printer.rb
@@ -52,14 +52,15 @@ files:
52
52
  - examples/graph.html
53
53
  - examples/graph.txt
54
54
  - ext/extconf.rb
55
+ - ext/extconf.rb.rej
55
56
  - ext/measure_allocations.h
56
57
  - ext/measure_cpu_time.h
58
+ - ext/measure_memory.h
57
59
  - ext/measure_process_time.h
58
60
  - ext/measure_wall_time.h
59
61
  - ext/ruby_prof.c
60
62
  - test/basic_test.rb
61
63
  - test/duplicate_names_test.rb
62
- - test/gc.log
63
64
  - test/line_number_test.rb
64
65
  - test/measure_mode_test.rb
65
66
  - test/module_test.rb
@@ -78,9 +79,9 @@ files:
78
79
  - test/test_suite.rb
79
80
  - test/thread_test.rb
80
81
  - test/timing_test.rb
81
- test_files:
82
- - test/test_helper.rb
83
- - test/test_suite.rb
82
+ has_rdoc: true
83
+ homepage: http://rubyforge.org/projects/ruby-prof/
84
+ post_install_message:
84
85
  rdoc_options:
85
86
  - --title
86
87
  - ruby-prof
@@ -88,19 +89,27 @@ rdoc_options:
88
89
  - --line-numbers
89
90
  - --main
90
91
  - README
91
- extra_rdoc_files:
92
- - bin/ruby-prof
93
- - ext/ruby_prof.c
94
- - examples/flat.txt
95
- - examples/graph.txt
96
- - examples/graph.html
97
- - README
98
- - LICENSE
99
- executables:
100
- - ruby-prof
101
- extensions:
102
- - ext/extconf.rb
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: 1.8.4
99
+ version:
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: "0"
105
+ version:
103
106
  requirements: []
104
107
 
105
- dependencies: []
106
-
108
+ rubyforge_project: ruby-prof
109
+ rubygems_version: 1.0.1
110
+ signing_key:
111
+ specification_version: 2
112
+ summary: Fast Ruby profiler
113
+ test_files:
114
+ - test/test_helper.rb
115
+ - test/test_suite.rb