ruby-prof 0.12.2 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +2 -2
- data/doc/LICENSE.html +1 -1
- data/doc/README_rdoc.html +2 -2
- data/doc/Rack.html +1 -1
- data/doc/Rack/RubyProf.html +2 -2
- data/doc/RubyProf.html +1 -1
- data/doc/RubyProf/AbstractPrinter.html +1 -1
- data/doc/RubyProf/AggregateCallInfo.html +1 -1
- data/doc/RubyProf/CallInfo.html +1 -1
- data/doc/RubyProf/CallInfoPrinter.html +1 -1
- data/doc/RubyProf/CallInfoVisitor.html +1 -1
- data/doc/RubyProf/CallStackPrinter.html +30 -27
- data/doc/RubyProf/CallTreePrinter.html +1 -1
- data/doc/RubyProf/Cmd.html +1 -1
- data/doc/RubyProf/DotPrinter.html +1 -1
- data/doc/RubyProf/FlatPrinter.html +1 -1
- data/doc/RubyProf/FlatPrinterWithLineNumbers.html +1 -1
- data/doc/RubyProf/GraphHtmlPrinter.html +14 -5
- data/doc/RubyProf/GraphPrinter.html +1 -1
- data/doc/RubyProf/MethodInfo.html +1 -1
- data/doc/RubyProf/MultiPrinter.html +1 -1
- data/doc/RubyProf/Profile.html +1 -1
- data/doc/RubyProf/ProfileTask.html +1 -1
- data/doc/RubyProf/Test.html +1 -1
- data/doc/RubyProf/Thread.html +1 -1
- data/doc/created.rid +11 -10
- data/doc/examples/flat_txt.html +1 -1
- data/doc/examples/graph_txt.html +1 -1
- data/doc/index.html +2 -2
- data/doc/js/darkfish.js +9 -7
- data/doc/table_of_contents.html +1 -1
- data/ext/ruby_prof/extconf.rb +2 -0
- data/ext/ruby_prof/rp_thread.c +24 -8
- data/ext/ruby_prof/rp_thread.h +5 -4
- data/ext/ruby_prof/ruby_prof.c +26 -10
- data/ext/ruby_prof/version.h +3 -3
- data/lib/ruby-prof/printers/call_info_printer.rb +2 -1
- data/lib/ruby-prof/printers/call_stack_printer.rb +7 -4
- data/lib/ruby-prof/printers/flat_printer.rb +1 -0
- data/lib/ruby-prof/printers/graph_html_printer.rb +13 -4
- data/lib/ruby-prof/printers/graph_printer.rb +2 -1
- data/lib/ruby-prof/rack.rb +1 -1
- data/ruby-prof.gemspec +1 -1
- data/test/fiber_test.rb +65 -0
- data/test/measure_process_time_test.rb +2 -2
- data/test/multi_printer_test.rb +4 -2
- data/test/printers_test.rb +2 -0
- data/test/stack_printer_test.rb +2 -2
- data/test/test_helper.rb +2 -0
- metadata +32 -25
@@ -28,6 +28,7 @@ module RubyProf
|
|
28
28
|
|
29
29
|
def print_header(thread)
|
30
30
|
@output << "Thread ID: %d\n" % thread.id
|
31
|
+
@output << "Fiber ID: %d\n" % thread.fiber_id unless thread.id == thread.fiber_id
|
31
32
|
@output << "Total: %0.6f\n" % thread.total_time
|
32
33
|
@output << "Sort by: #{sort_method}\n"
|
33
34
|
@output << "\n"
|
@@ -60,7 +60,7 @@ module RubyProf
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def method_href(thread, method)
|
63
|
-
h(method.full_name.gsub(/[><#\.\?=:]/,"_") + "_" + thread.
|
63
|
+
h(method.full_name.gsub(/[><#\.\?=:]/,"_") + "_" + thread.fiber_id.to_s)
|
64
64
|
end
|
65
65
|
|
66
66
|
def file_link(path, linenum)
|
@@ -139,11 +139,17 @@ module RubyProf
|
|
139
139
|
<table>
|
140
140
|
<tr>
|
141
141
|
<th>Thread ID</th>
|
142
|
+
<% if RUBY_VERSION >= "1.9" %>
|
143
|
+
<th>Fiber ID</th>
|
144
|
+
<% end %>
|
142
145
|
<th>Total Time</th>
|
143
146
|
</tr>
|
144
147
|
<% for thread in @result.threads %>
|
145
148
|
<tr>
|
146
|
-
|
149
|
+
<% if RUBY_VERSION >= "1.9" %>
|
150
|
+
<td><%= thread.id %></td>
|
151
|
+
<% end %>
|
152
|
+
<td><a href="#<%= thread.fiber_id %>"><%= thread.fiber_id %></a></td>
|
147
153
|
<td><%= thread.total_time %></td>
|
148
154
|
</tr>
|
149
155
|
<% end %>
|
@@ -153,8 +159,11 @@ module RubyProf
|
|
153
159
|
<% for thread in @result.threads
|
154
160
|
methods = thread.methods
|
155
161
|
total_time = thread.total_time %>
|
156
|
-
|
157
|
-
|
162
|
+
<% if RUBY_VERSION >= "1.9" %>
|
163
|
+
<h2><a name="<%= thread.fiber_id %>">Thread <%= thread.id %>, Fiber: <%= thread.fiber_id %></a></h2>
|
164
|
+
<% else %>
|
165
|
+
<h2><a name="<%= thread.fiber_id %>">Thread <%= thread.fiber_id %></a></h2>
|
166
|
+
<% end %>
|
158
167
|
<table>
|
159
168
|
<thead>
|
160
169
|
<tr>
|
@@ -22,6 +22,7 @@ module RubyProf
|
|
22
22
|
|
23
23
|
def print_header(thread)
|
24
24
|
@output << "Thread ID: #{thread.id}\n"
|
25
|
+
@output << "Fiber ID: #{thread.fiber_id}\n" unless thread.id == thread.fiber_id
|
25
26
|
@output << "Total Time: #{thread.total_time}\n"
|
26
27
|
@output << "Sort by: #{sort_method}\n"
|
27
28
|
@output << "\n"
|
@@ -112,4 +113,4 @@ module RubyProf
|
|
112
113
|
@output << "* indicates recursively called methods\n"
|
113
114
|
end
|
114
115
|
end
|
115
|
-
end
|
116
|
+
end
|
data/lib/ruby-prof/rack.rb
CHANGED
@@ -13,7 +13,7 @@ module Rack
|
|
13
13
|
::RubyProf::GraphHtmlPrinter => 'graph.html',
|
14
14
|
::RubyProf::CallStackPrinter => 'call_stack.html'}
|
15
15
|
|
16
|
-
@skip_paths = options[:skip_paths] || [%r{^/assets}, %r{\.css$}, %r{\.js}, %r{\.png}, %r{\.jpeg}]
|
16
|
+
@skip_paths = options[:skip_paths] || [%r{^/assets}, %r{\.css$}, %r{\.js$}, %r{\.png$}, %r{\.jpeg$}, %r{\.jpg$}, %r{\.gif$}]
|
17
17
|
end
|
18
18
|
|
19
19
|
def call(env)
|
data/ruby-prof.gemspec
CHANGED
@@ -53,7 +53,7 @@ EOF
|
|
53
53
|
|
54
54
|
spec.test_files = Dir["test/test_*.rb"]
|
55
55
|
spec.required_ruby_version = '>= 1.8.7'
|
56
|
-
spec.date =
|
56
|
+
spec.date = Time.now.strftime('%Y-%m-%d')
|
57
57
|
spec.homepage = 'https://github.com/rdp/ruby-prof'
|
58
58
|
spec.add_development_dependency('minitest')
|
59
59
|
spec.add_development_dependency('rake-compiler')
|
data/test/fiber_test.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
require File.expand_path('../test_helper', __FILE__)
|
5
|
+
require 'timeout'
|
6
|
+
require 'set'
|
7
|
+
begin
|
8
|
+
require 'fiber'
|
9
|
+
rescue LoadError
|
10
|
+
end
|
11
|
+
|
12
|
+
# -- Tests ----
|
13
|
+
class FiberTest < Test::Unit::TestCase
|
14
|
+
|
15
|
+
def fiber_test
|
16
|
+
@fiber_ids << Fiber.current.object_id
|
17
|
+
enum = Enumerator.new do |yielder|
|
18
|
+
[1,2].each do |x|
|
19
|
+
@fiber_ids << Fiber.current.object_id
|
20
|
+
sleep 0.1
|
21
|
+
yielder.yield x
|
22
|
+
end
|
23
|
+
end
|
24
|
+
while true
|
25
|
+
begin
|
26
|
+
x = enum.next
|
27
|
+
rescue StopIteration
|
28
|
+
break
|
29
|
+
end
|
30
|
+
end
|
31
|
+
sleep 0.1
|
32
|
+
end
|
33
|
+
|
34
|
+
def setup
|
35
|
+
# Need to use wall time for this test due to the sleep calls
|
36
|
+
RubyProf::measure_mode = RubyProf::WALL_TIME
|
37
|
+
@fiber_ids = Set.new
|
38
|
+
@root_fiber = Fiber.current.object_id
|
39
|
+
@thread_id = Thread.current.object_id
|
40
|
+
@result = RubyProf.profile { fiber_test }
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_fibers
|
44
|
+
profiled_fiber_ids = @result.threads.map(&:fiber_id)
|
45
|
+
assert_equal(2, @result.threads.length)
|
46
|
+
assert_equal([@thread_id], @result.threads.map(&:id).uniq)
|
47
|
+
assert_equal(@fiber_ids, Set.new(profiled_fiber_ids))
|
48
|
+
|
49
|
+
assert profiled_fiber_ids.include?(@root_fiber)
|
50
|
+
assert(root_fiber_profile = @result.threads.detect{|t| t.fiber_id == @root_fiber})
|
51
|
+
assert(enum_fiber_profile = @result.threads.detect{|t| t.fiber_id != @root_fiber})
|
52
|
+
|
53
|
+
assert_in_delta(0.3, root_fiber_profile.total_time, 0.01)
|
54
|
+
assert_in_delta(0.2, enum_fiber_profile.total_time, 0.01)
|
55
|
+
|
56
|
+
assert(method_next = root_fiber_profile.methods.detect{|m| m.full_name == "Enumerator#next"})
|
57
|
+
assert(method_each = enum_fiber_profile.methods.detect{|m| m.full_name == "Enumerator#each"})
|
58
|
+
|
59
|
+
assert_in_delta(0.2, method_next.total_time, 0.01)
|
60
|
+
assert_in_delta(0.2, method_each.total_time, 0.01)
|
61
|
+
|
62
|
+
# RubyProf::CallInfoPrinter.new(@result).print
|
63
|
+
end
|
64
|
+
|
65
|
+
end if RUBY_VERSION >= "1.9"
|
@@ -42,12 +42,12 @@ class MeasureProcessTimeTest < Test::Unit::TestCase
|
|
42
42
|
|
43
43
|
# Check times
|
44
44
|
assert_equal("MeasureProcessTimeTest#test_primes", methods[0].full_name)
|
45
|
-
assert_in_delta(total_time, methods[0].total_time, 0.
|
45
|
+
assert_in_delta(total_time, methods[0].total_time, 0.02)
|
46
46
|
assert_in_delta(0.0, methods[0].wait_time, 0.01)
|
47
47
|
assert_in_delta(0.0, methods[0].self_time, 0.01)
|
48
48
|
|
49
49
|
assert_equal("Object#run_primes", methods[1].full_name)
|
50
|
-
assert_in_delta(total_time, methods[1].total_time, 0.
|
50
|
+
assert_in_delta(total_time, methods[1].total_time, 0.02)
|
51
51
|
assert_in_delta(0.0, methods[1].wait_time, 0.01)
|
52
52
|
assert_in_delta(0.0, methods[1].self_time, 0.01)
|
53
53
|
|
data/test/multi_printer_test.rb
CHANGED
@@ -45,17 +45,19 @@ class MultiPrinterTest < Test::Unit::TestCase
|
|
45
45
|
\s*<table>
|
46
46
|
\s*<tr>
|
47
47
|
\s*<th>Thread ID</th>
|
48
|
+
\s*(<th>Fiber ID</th>)?
|
48
49
|
\s*<th>Total Time</th>
|
49
50
|
\s*</tr>
|
50
51
|
\s*
|
51
52
|
\s*<tr>
|
53
|
+
\s*(<td>([\.0-9]+)</td>)?
|
52
54
|
\s*<td><a href="#-?\d+">-?\d+</a></td>
|
53
|
-
\s*<td>([\.0-
|
55
|
+
\s*<td>([\.0-9e]+)</td>
|
54
56
|
\s*</tr>
|
55
57
|
\s*
|
56
58
|
\s*</table>')
|
57
59
|
assert_match(re, graph)
|
58
|
-
display_time = $
|
60
|
+
display_time = $4.to_f
|
59
61
|
assert_in_delta expected_time, display_time, 0.5
|
60
62
|
end
|
61
63
|
|
data/test/printers_test.rb
CHANGED
@@ -75,6 +75,7 @@ class PrintersTest < Test::Unit::TestCase
|
|
75
75
|
printer.print(output)
|
76
76
|
|
77
77
|
assert_match(/Thread ID: -?\d+/i, output)
|
78
|
+
assert_match(/Fiber ID: -?\d+/i, output) unless RUBY_VERSION =~ /^1.8/
|
78
79
|
assert_match(/Total: \d+\.\d+/i, output)
|
79
80
|
assert_match(/Object#run_primes/i, output)
|
80
81
|
output
|
@@ -112,6 +113,7 @@ class PrintersTest < Test::Unit::TestCase
|
|
112
113
|
printer.print(output)
|
113
114
|
|
114
115
|
assert_match(/Thread ID: -?\d+/i, output)
|
116
|
+
assert_match(/Fiber ID: -?\d+/i, output) unless RUBY_VERSION =~ /^1.8/
|
115
117
|
assert_match(/Total Time: \d+\.\d+/i, output)
|
116
118
|
assert_match(/Object#run_primes/i, output)
|
117
119
|
end
|
data/test/stack_printer_test.rb
CHANGED
@@ -43,8 +43,8 @@ class StackPrinterTest < Test::Unit::TestCase
|
|
43
43
|
file_contents = nil
|
44
44
|
assert_nothing_raised { file_contents = print(result) }
|
45
45
|
# TODO: why are thread ids negative on travis-ci.org (32 bit build maybe?)
|
46
|
-
assert_match(/Thread: (-?\d+) \(100\.00% ~ ([\.0-9]+)\)/, file_contents)
|
47
|
-
actual_time = $
|
46
|
+
assert_match(/Thread: (-?\d+)(, Fiber: (-?\d+))? \(100\.00% ~ ([\.0-9]+)\)/, file_contents)
|
47
|
+
actual_time = $4.to_f
|
48
48
|
assert_in_delta(expected_time, actual_time, 0.5)
|
49
49
|
end
|
50
50
|
|
data/test/test_helper.rb
CHANGED
@@ -13,6 +13,8 @@ if ENV["RM_INFO"] || ENV["TEAMCITY_VERSION"]
|
|
13
13
|
MiniTest::Reporters.use!
|
14
14
|
end
|
15
15
|
|
16
|
+
require "minitest/pride"
|
17
|
+
|
16
18
|
# To make testing/debugging easier, test within this source tree versus an installed gem
|
17
19
|
dir = File.dirname(__FILE__)
|
18
20
|
root = File.expand_path(File.join(dir, '..'))
|
metadata
CHANGED
@@ -1,71 +1,77 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-prof
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.12.2
|
5
4
|
prerelease:
|
5
|
+
version: 0.13.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Shugo Maeda, Charlie Savage, Roger Pack, Stefan Kaes
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-03-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: minitest
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
17
|
requirements:
|
19
|
-
- -
|
18
|
+
- - ! '>='
|
20
19
|
- !ruby/object:Gem::Version
|
21
20
|
version: '0'
|
21
|
+
none: false
|
22
22
|
type: :development
|
23
|
-
prerelease: false
|
24
23
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
24
|
requirements:
|
27
|
-
- -
|
25
|
+
- - ! '>='
|
28
26
|
- !ruby/object:Gem::Version
|
29
27
|
version: '0'
|
28
|
+
none: false
|
29
|
+
prerelease: false
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: rake-compiler
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
33
|
requirements:
|
35
|
-
- -
|
34
|
+
- - ! '>='
|
36
35
|
- !ruby/object:Gem::Version
|
37
36
|
version: '0'
|
37
|
+
none: false
|
38
38
|
type: :development
|
39
|
-
prerelease: false
|
40
39
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
40
|
requirements:
|
43
|
-
- -
|
41
|
+
- - ! '>='
|
44
42
|
- !ruby/object:Gem::Version
|
45
43
|
version: '0'
|
44
|
+
none: false
|
45
|
+
prerelease: false
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: rdoc
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
49
|
requirements:
|
51
|
-
- -
|
50
|
+
- - ! '>='
|
52
51
|
- !ruby/object:Gem::Version
|
53
52
|
version: '0'
|
53
|
+
none: false
|
54
54
|
type: :development
|
55
|
-
prerelease: false
|
56
55
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
56
|
requirements:
|
59
|
-
- -
|
57
|
+
- - ! '>='
|
60
58
|
- !ruby/object:Gem::Version
|
61
59
|
version: '0'
|
62
|
-
|
63
|
-
|
60
|
+
none: false
|
61
|
+
prerelease: false
|
62
|
+
description: ! 'ruby-prof is a fast code profiler for Ruby. It is a C extension and
|
63
|
+
|
64
64
|
therefore is many times faster than the standard Ruby profiler. It
|
65
|
+
|
65
66
|
supports both flat and graph profiles. For each method, graph profiles
|
67
|
+
|
66
68
|
show how long the method ran, which methods called it and which
|
69
|
+
|
67
70
|
methods it called. RubyProf generate both text and html and can output
|
71
|
+
|
68
72
|
it to standard out or to a file.
|
73
|
+
|
74
|
+
'
|
69
75
|
email: shugo@ruby-lang.org, cfis@savagexi.com, rogerdpack@gmail.com, skaes@railsexpress.de
|
70
76
|
executables:
|
71
77
|
- ruby-prof
|
@@ -212,6 +218,7 @@ files:
|
|
212
218
|
- test/exceptions_test.rb
|
213
219
|
- test/exclude_threads_test.rb
|
214
220
|
- test/exec_test.rb
|
221
|
+
- test/fiber_test.rb
|
215
222
|
- test/line_number_test.rb
|
216
223
|
- test/measure_allocations_test.rb
|
217
224
|
- test/measure_cpu_time_test.rb
|
@@ -243,20 +250,20 @@ rdoc_options: []
|
|
243
250
|
require_paths:
|
244
251
|
- lib
|
245
252
|
required_ruby_version: !ruby/object:Gem::Requirement
|
246
|
-
none: false
|
247
253
|
requirements:
|
248
|
-
- -
|
254
|
+
- - ! '>='
|
249
255
|
- !ruby/object:Gem::Version
|
250
256
|
version: 1.8.7
|
251
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
252
257
|
none: false
|
258
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
253
259
|
requirements:
|
254
|
-
- -
|
260
|
+
- - ! '>='
|
255
261
|
- !ruby/object:Gem::Version
|
256
|
-
version: '0'
|
257
262
|
segments:
|
258
263
|
- 0
|
259
|
-
hash: -
|
264
|
+
hash: -3655921953818653003
|
265
|
+
version: '0'
|
266
|
+
none: false
|
260
267
|
requirements: []
|
261
268
|
rubyforge_project:
|
262
269
|
rubygems_version: 1.8.25
|