ruby-prof 0.11.0.rc1 → 0.11.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/CHANGES +20 -5
  2. data/README.rdoc +10 -3
  3. data/ext/ruby_prof/rp_call_info.c +108 -79
  4. data/ext/ruby_prof/rp_call_info.h +1 -0
  5. data/ext/ruby_prof/rp_measure_cpu_time.c +111 -111
  6. data/ext/ruby_prof/rp_measure_gc_runs.c +1 -1
  7. data/ext/ruby_prof/rp_measure_memory.c +1 -1
  8. data/ext/ruby_prof/rp_measure_process_time.c +71 -71
  9. data/ext/ruby_prof/rp_measure_wall_time.c +1 -1
  10. data/ext/ruby_prof/rp_method.c +143 -73
  11. data/ext/ruby_prof/rp_method.h +7 -4
  12. data/ext/ruby_prof/rp_stack.c +16 -1
  13. data/ext/ruby_prof/rp_stack.h +4 -1
  14. data/ext/ruby_prof/rp_thread.c +165 -35
  15. data/ext/ruby_prof/rp_thread.h +8 -2
  16. data/ext/ruby_prof/ruby_prof.c +164 -171
  17. data/ext/ruby_prof/ruby_prof.h +53 -54
  18. data/ext/ruby_prof/vc/ruby_prof.sln +26 -0
  19. data/ext/ruby_prof/vc/ruby_prof.vcxproj +109 -0
  20. data/ext/ruby_prof/vc/ruby_prof_18.vcxproj +105 -0
  21. data/lib/ruby-prof/aggregate_call_info.rb +9 -7
  22. data/lib/ruby-prof/call_info.rb +2 -27
  23. data/lib/ruby-prof/call_info_visitor.rb +42 -0
  24. data/lib/ruby-prof/{empty.png → images/empty.png} +0 -0
  25. data/lib/ruby-prof/{minus.png → images/minus.png} +0 -0
  26. data/lib/ruby-prof/{plus.png → images/plus.png} +0 -0
  27. data/lib/ruby-prof/method_info.rb +13 -15
  28. data/lib/ruby-prof/{abstract_printer.rb → printers/abstract_printer.rb} +36 -2
  29. data/lib/ruby-prof/printers/call_info_printer.rb +40 -0
  30. data/lib/ruby-prof/{call_stack_printer.rb → printers/call_stack_printer.rb} +11 -16
  31. data/lib/ruby-prof/{call_tree_printer.rb → printers/call_tree_printer.rb} +4 -4
  32. data/lib/ruby-prof/{dot_printer.rb → printers/dot_printer.rb} +11 -31
  33. data/lib/ruby-prof/{flat_printer.rb → printers/flat_printer.rb} +26 -35
  34. data/lib/ruby-prof/{flat_printer_with_line_numbers.rb → printers/flat_printer_with_line_numbers.rb} +14 -25
  35. data/lib/ruby-prof/printers/graph_html_printer.rb +248 -0
  36. data/lib/ruby-prof/{graph_printer.rb → printers/graph_printer.rb} +31 -73
  37. data/lib/ruby-prof/{multi_printer.rb → printers/multi_printer.rb} +0 -0
  38. data/lib/ruby-prof/profile.rb +27 -22
  39. data/lib/ruby-prof/rack.rb +22 -12
  40. data/ruby-prof.gemspec +58 -0
  41. data/test/aggregate_test.rb +6 -6
  42. data/test/call_info_visitor_test.rb +31 -0
  43. data/test/duplicate_names_test.rb +1 -1
  44. data/test/dynamic_method_test.rb +1 -1
  45. data/test/enumerable_test.rb +1 -1
  46. data/test/exclude_threads_test.rb +2 -2
  47. data/test/gc_test.rb +35 -0
  48. data/test/line_number_test.rb +2 -2
  49. data/test/measure_cpu_time_test.rb +5 -5
  50. data/test/measure_process_time_test.rb +5 -5
  51. data/test/measure_wall_time_test.rb +5 -5
  52. data/test/method_elimination_test.rb +3 -3
  53. data/test/module_test.rb +1 -1
  54. data/test/no_method_class_test.rb +1 -1
  55. data/test/printers_test.rb +16 -8
  56. data/test/recursive_test.rb +115 -91
  57. data/test/stack_test.rb +1 -1
  58. data/test/start_stop_test.rb +13 -13
  59. data/test/summarize_test.rb +48 -0
  60. data/test/test_suite.rb +1 -0
  61. data/test/thread_test.rb +16 -12
  62. data/test/unique_call_path_test.rb +10 -10
  63. metadata +64 -85
  64. data/lib/1.8/ruby_prof.so +0 -0
  65. data/lib/1.9/ruby_prof.exp +0 -0
  66. data/lib/1.9/ruby_prof.ilk +0 -0
  67. data/lib/1.9/ruby_prof.lib +0 -0
  68. data/lib/1.9/ruby_prof.pdb +0 -0
  69. data/lib/1.9/ruby_prof.so +0 -0
  70. data/lib/ruby-prof.rb +0 -70
  71. data/lib/ruby-prof/graph_html_printer.rb +0 -286
  72. data/lib/ruby-prof/symbol_to_proc.rb +0 -10
  73. data/lib/ruby_prof.exp +0 -0
  74. data/lib/ruby_prof.ilk +0 -0
  75. data/lib/ruby_prof.lib +0 -0
  76. data/lib/ruby_prof.pdb +0 -0
  77. data/lib/ruby_prof.so +0 -0
  78. data/lib/unprof.rb +0 -10
  79. data/test/do_nothing.rb +0 -0
data/lib/1.8/ruby_prof.so DELETED
Binary file
Binary file
Binary file
Binary file
Binary file
data/lib/1.9/ruby_prof.so DELETED
Binary file
data/lib/ruby-prof.rb DELETED
@@ -1,70 +0,0 @@
1
- # encoding: utf-8
2
-
3
- # Load the C-based binding.
4
- begin
5
- RUBY_VERSION =~ /(\d+.\d+)/
6
- require "#{$1}/ruby_prof"
7
- rescue LoadError
8
- require "ruby_prof"
9
- end
10
-
11
-
12
- module RubyProf
13
- def self.camelcase(phrase)
14
- ('_' + phrase).gsub(/_([a-z])/){|b| b[1..1].upcase}
15
- end
16
-
17
- lib_dir = File.dirname(__FILE__) + '/ruby-prof/'
18
-
19
- for file in ['abstract_printer', 'aggregate_call_info', 'flat_printer', 'flat_printer_with_line_numbers',
20
- 'graph_printer', 'graph_html_printer', 'call_tree_printer', 'call_stack_printer', 'multi_printer', 'dot_printer']
21
- autoload camelcase(file), lib_dir + file
22
- end
23
-
24
- # A few need to be loaded manually their classes were already defined by the .so file so autoload won't work for them.
25
- # plus we need them anyway
26
- for name in ['profile', 'method_info', 'call_info']
27
- require lib_dir + name
28
- end
29
-
30
- # Compatability layer for suporting old api
31
- require lib_dir + 'compatibility'
32
-
33
- # we don't require unprof.rb, as well, purposefully
34
-
35
- # Checks if the user specified the clock mode via
36
- # the RUBY_PROF_MEASURE_MODE environment variable
37
- def self.figure_measure_mode
38
- case ENV["RUBY_PROF_MEASURE_MODE"]
39
- when "wall" || "wall_time"
40
- RubyProf.measure_mode = RubyProf::WALL_TIME
41
- when "cpu" || "cpu_time"
42
- if ENV.key?("RUBY_PROF_CPU_FREQUENCY")
43
- RubyProf.cpu_frequency = ENV["RUBY_PROF_CPU_FREQUENCY"].to_f
44
- else
45
- begin
46
- open("/proc/cpuinfo") do |f|
47
- f.each_line do |line|
48
- s = line.slice(/cpu MHz\s*:\s*(.*)/, 1)
49
- if s
50
- RubyProf.cpu_frequency = s.to_f * 1000000
51
- break
52
- end
53
- end
54
- end
55
- rescue Errno::ENOENT
56
- end
57
- end
58
- RubyProf.measure_mode = RubyProf::CPU_TIME
59
- when "allocations"
60
- RubyProf.measure_mode = RubyProf::ALLOCATIONS
61
- when "memory"
62
- RubyProf.measure_mode = RubyProf::MEMORY
63
- else
64
- # the default...
65
- RubyProf.measure_mode = RubyProf::PROCESS_TIME
66
- end
67
- end
68
- end
69
-
70
- RubyProf::figure_measure_mode
@@ -1,286 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'erb'
4
-
5
- module RubyProf
6
- # Generates graph[link:files/examples/graph_html.html] profile reports as html.
7
- # To use the graph html printer:
8
- #
9
- # result = RubyProf.profile do
10
- # [code to profile]
11
- # end
12
- #
13
- # printer = RubyProf::GraphHtmlPrinter.new(result)
14
- # printer.print(STDOUT, :min_percent=>0)
15
- #
16
- # The constructor takes two arguments. The first is
17
- # a RubyProf::Result object generated from a profiling
18
- # run. The second is the minimum %total (the methods
19
- # total time divided by the overall total time) that
20
- # a method must take for it to be printed out in
21
- # the report. Use this parameter to eliminate methods
22
- # that are not important to the overall profiling results.
23
-
24
- class GraphHtmlPrinter < AbstractPrinter
25
- include ERB::Util
26
-
27
- PERCENTAGE_WIDTH = 8
28
- TIME_WIDTH = 10
29
- CALL_WIDTH = 20
30
-
31
- # Create a GraphPrinter. Result is a RubyProf::Result
32
- # object generated from a profiling run.
33
- def initialize(result)
34
- super(result)
35
- @thread_times = Hash.new
36
- calculate_thread_times
37
- end
38
-
39
- # Print a graph html report to the provided output.
40
- #
41
- # output - Any IO oject, including STDOUT or a file.
42
- # The default value is STDOUT.
43
- #
44
- # options - Hash of print options. See #setup_options
45
- # for more information.
46
- #
47
- # unique options are:
48
- # :filename - specify a file to use that contains the ERB
49
- # template to use, instead of the built-in self.template
50
- #
51
- # :template - specify an ERB template to use, instead of the
52
- # built-in self.template
53
- #
54
- def print(output = STDOUT, options = {})
55
- @output = output
56
- setup_options(options)
57
-
58
- filename = options[:filename]
59
- template = filename ? File.read(filename).untaint : (options[:template] || self.template)
60
- _erbout = @output
61
- erb = ERB.new(template, nil, nil)
62
- erb.filename = filename
63
- @output << erb.result(binding)
64
- end
65
-
66
- def total_time(call_infos)
67
- sum(call_infos.map{|ci| ci.total_time})
68
- end
69
-
70
- def sum(a)
71
- a.inject(0.0){|s,t| s+=t}
72
- end
73
-
74
- # These methods should be private but then ERB doesn't
75
- # work. Turn off RDOC though
76
- #--
77
- def calculate_thread_times
78
- # Cache thread times since this is an expensive
79
- # operation with the required sorting
80
- @overall_threads_time = 0.0
81
- @thread_times = Hash.new
82
- @result.threads.each do |thread_id, methods|
83
- roots = methods.select{|m| m.root?}
84
- thread_total_time = sum(roots.map{|r| self.total_time(r.call_infos)})
85
- @overall_threads_time += thread_total_time
86
- @thread_times[thread_id] = thread_total_time
87
- end
88
- end
89
-
90
- def thread_time(thread_id)
91
- @thread_times[thread_id]
92
- end
93
-
94
- def total_percent(thread_id, method)
95
- overall_time = self.thread_time(thread_id)
96
- (method.total_time/overall_time) * 100
97
- end
98
-
99
- def self_percent(method)
100
- overall_time = self.thread_time(method.thread_id)
101
- (method.self_time/overall_time) * 100
102
- end
103
-
104
- # Creates a link to a method. Note that we do not create
105
- # links to methods which are under the min_perecent
106
- # specified by the user, since they will not be
107
- # printed out.
108
- def create_link(thread_id, method)
109
- if self.total_percent(thread_id, method) < min_percent
110
- # Just return name
111
- h method.full_name
112
- else
113
- href = '#' + method_href(thread_id, method)
114
- "<a href=\"#{href}\">#{h method.full_name}</a>"
115
- end
116
- end
117
-
118
- def method_href(thread_id, method)
119
- h(method.full_name.gsub(/[><#\.\?=:]/,"_") + "_" + thread_id.to_s)
120
- end
121
-
122
- def file_link(path, linenum)
123
- srcfile = File.expand_path(path)
124
- if srcfile =~ /\/ruby_runtime$/
125
- ""
126
- else
127
- if RUBY_PLATFORM =~ /darwin/
128
- "<a href=\"txmt://open?url=file://#{h srcfile}&line=#{linenum}\" title=\"#{h srcfile}:#{linenum}\">#{linenum}</a>"
129
- else
130
- "<a href=\"file://#{h srcfile}##{linenum}\" title=\"#{h srcfile}:#{linenum}\">#{linenum}</a>"
131
- end
132
- end
133
- end
134
-
135
- def template
136
- '
137
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
138
- <html>
139
- <head>
140
- <style media="all" type="text/css">
141
- table {
142
- border-collapse: collapse;
143
- border: 1px solid #CCC;
144
- font-family: Verdana, Arial, Helvetica, sans-serif;
145
- font-size: 9pt;
146
- line-height: normal;
147
- width: 100%;
148
- }
149
-
150
- th {
151
- text-align: center;
152
- border-top: 1px solid #FB7A31;
153
- border-bottom: 1px solid #FB7A31;
154
- background: #FFC;
155
- padding: 0.3em;
156
- border-left: 1px solid silver;
157
- }
158
-
159
- tr.break td {
160
- border: 0;
161
- border-top: 1px solid #FB7A31;
162
- padding: 0;
163
- margin: 0;
164
- }
165
-
166
- tr.method td {
167
- font-weight: bold;
168
- }
169
-
170
- td {
171
- padding: 0.3em;
172
- }
173
-
174
- td:first-child {
175
- width: 190px;
176
- }
177
-
178
- td {
179
- border-left: 1px solid #CCC;
180
- text-align: center;
181
- }
182
-
183
- .method_name {
184
- text-align: left;
185
- }
186
- </style>
187
- </head>
188
- <body>
189
- <h1>Profile Report</h1>
190
- <!-- Threads Table -->
191
- <table>
192
- <tr>
193
- <th>Thread ID</th>
194
- <th>Total Time</th>
195
- </tr>
196
- <% for thread_id in @result.threads.keys.sort %>
197
- <tr>
198
- <td><a href="#<%= thread_id %>"><%= thread_id %></a></td>
199
- <td><%= thread_time(thread_id) %></td>
200
- </tr>
201
- <% end %>
202
- </table>
203
-
204
- <!-- Methods Tables -->
205
- <% for thread_id in @result.threads.keys.sort
206
- methods = @result.threads[thread_id]
207
- total_time = thread_time(thread_id) %>
208
- <h2><a name="<%= thread_id %>">Thread <%= thread_id %></a></h2>
209
-
210
- <table>
211
- <tr>
212
- <th><%= sprintf("%#{PERCENTAGE_WIDTH}s", "%Total") %></th>
213
- <th><%= sprintf("%#{PERCENTAGE_WIDTH}s", "%Self") %></th>
214
- <th><%= sprintf("%#{TIME_WIDTH}s", "Total") %></th>
215
- <th><%= sprintf("%#{TIME_WIDTH}s", "Self") %></th>
216
- <th><%= sprintf("%#{TIME_WIDTH}s", "Wait") %></th>
217
- <th><%= sprintf("%#{TIME_WIDTH+2}s", "Child") %></th>
218
- <th><%= sprintf("%#{CALL_WIDTH}s", "Calls") %></th>
219
- <th class="method_name">Name</th>
220
- <th>Line</th>
221
- </tr>
222
-
223
- <% min_time = @options[:min_time] || (@options[:nonzero] ? 0.005 : nil)
224
- methods.sort_by(&sort_method).reverse_each do |method|
225
- total_percentage = (method.total_time/total_time) * 100
226
- next if total_percentage < min_percent
227
- next if min_time && method.total_time < min_time
228
- self_percentage = (method.self_time/total_time) * 100 %>
229
-
230
- <!-- Parents -->
231
- <% for caller in method.aggregate_parents.sort_by(&:total_time)
232
- next unless caller.parent
233
- next if min_time && caller.total_time < min_time %>
234
- <tr>
235
- <td>&nbsp;</td>
236
- <td>&nbsp;</td>
237
- <td><%= sprintf("%#{TIME_WIDTH}.2f", caller.total_time) %></td>
238
- <td><%= sprintf("%#{TIME_WIDTH}.2f", caller.self_time) %></td>
239
- <td><%= sprintf("%#{TIME_WIDTH}.2f", caller.wait_time) %></td>
240
- <td><%= sprintf("%#{TIME_WIDTH}.2f", caller.children_time) %></td>
241
- <% called = "#{caller.called}/#{method.called}" %>
242
- <td><%= sprintf("%#{CALL_WIDTH}s", called) %></td>
243
- <td class="method_name"><%= create_link(thread_id, caller.parent.target) %></td>
244
- <td><%= file_link(caller.parent.target.source_file, caller.line) %></td>
245
- </tr>
246
- <% end %>
247
-
248
- <tr class="method">
249
- <td><%= sprintf("%#{PERCENTAGE_WIDTH-1}.2f\%", total_percentage) %></td>
250
- <td><%= sprintf("%#{PERCENTAGE_WIDTH-1}.2f\%", self_percentage) %></td>
251
- <td><%= sprintf("%#{TIME_WIDTH}.2f", method.total_time) %></td>
252
- <td><%= sprintf("%#{TIME_WIDTH}.2f", method.self_time) %></td>
253
- <td><%= sprintf("%#{TIME_WIDTH}.2f", method.wait_time) %></td>
254
- <td><%= sprintf("%#{TIME_WIDTH}.2f", method.children_time) %></td>
255
- <td><%= sprintf("%#{CALL_WIDTH}i", method.called) %></td>
256
- <td class="method_name"><a name="<%= method_href(thread_id, method) %>"><%= h method.full_name %></a></td>
257
- <td><%= file_link(method.source_file, method.line) %></td>
258
- </tr>
259
-
260
- <!-- Children -->
261
- <% for callee in method.aggregate_children.sort_by(&:total_time).reverse %>
262
- <% next if min_time && callee.total_time < min_time %>
263
- <tr>
264
- <td>&nbsp;</td>
265
- <td>&nbsp;</td>
266
- <td><%= sprintf("%#{TIME_WIDTH}.2f", callee.total_time) %></td>
267
- <td><%= sprintf("%#{TIME_WIDTH}.2f", callee.self_time) %></td>
268
- <td><%= sprintf("%#{TIME_WIDTH}.2f", callee.wait_time) %></td>
269
- <td><%= sprintf("%#{TIME_WIDTH}.2f", callee.children_time) %></td>
270
- <% called = "#{callee.called}/#{callee.target.called}" %>
271
- <td><%= sprintf("%#{CALL_WIDTH}s", called) %></td>
272
- <td class="method_name"><%= create_link(thread_id, callee.target) %></td>
273
- <td><%= file_link(method.source_file, callee.line) %></td>
274
- </tr>
275
- <% end %>
276
- <!-- Create divider row -->
277
- <tr class="break"><td colspan="9"></td></tr>
278
- <% end %>
279
- </table>
280
- <% end %>
281
- </body>
282
- </html>'
283
- end
284
- end
285
- end
286
-
@@ -1,10 +0,0 @@
1
- # encoding: utf-8
2
-
3
- unless (:a.respond_to?(:to_proc))
4
- class Symbol
5
- def to_proc
6
- proc {|stuff| stuff.send(self)}
7
- end
8
- end
9
- end
10
-
data/lib/ruby_prof.exp DELETED
Binary file
data/lib/ruby_prof.ilk DELETED
Binary file
data/lib/ruby_prof.lib DELETED
Binary file
data/lib/ruby_prof.pdb DELETED
Binary file
data/lib/ruby_prof.so DELETED
Binary file
data/lib/unprof.rb DELETED
@@ -1,10 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require "ruby-prof"
4
-
5
- at_exit {
6
- result = RubyProf.stop
7
- printer = RubyProf::FlatPrinter.new(result)
8
- printer.print(STDOUT)
9
- }
10
- RubyProf.start
data/test/do_nothing.rb DELETED
File without changes