ruby-prof 0.8.1-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +221 -0
- data/LICENSE +23 -0
- data/README +432 -0
- data/Rakefile +159 -0
- data/bin/ruby-prof +224 -0
- data/examples/flat.txt +55 -0
- data/examples/graph.html +823 -0
- data/examples/graph.txt +170 -0
- data/ext/ruby_prof/measure_allocations.h +58 -0
- data/ext/ruby_prof/measure_cpu_time.h +152 -0
- data/ext/ruby_prof/measure_gc_runs.h +76 -0
- data/ext/ruby_prof/measure_gc_time.h +57 -0
- data/ext/ruby_prof/measure_memory.h +101 -0
- data/ext/ruby_prof/measure_process_time.h +52 -0
- data/ext/ruby_prof/measure_wall_time.h +53 -0
- data/ext/ruby_prof/mingw/Rakefile +23 -0
- data/ext/ruby_prof/mingw/build.rake +38 -0
- data/ext/ruby_prof/ruby_prof.c +1747 -0
- data/ext/ruby_prof/ruby_prof.h +188 -0
- data/ext/ruby_prof/version.h +4 -0
- data/lib/1.8/ruby_prof.so +0 -0
- data/lib/1.9/ruby_prof.so +0 -0
- data/lib/ruby-prof.rb +56 -0
- data/lib/ruby-prof/abstract_printer.rb +41 -0
- data/lib/ruby-prof/aggregate_call_info.rb +62 -0
- data/lib/ruby-prof/call_info.rb +47 -0
- data/lib/ruby-prof/call_tree_printer.rb +84 -0
- data/lib/ruby-prof/flat_printer.rb +78 -0
- data/lib/ruby-prof/flat_printer_with_line_numbers.rb +72 -0
- data/lib/ruby-prof/graph_html_printer.rb +256 -0
- data/lib/ruby-prof/graph_printer.rb +157 -0
- data/lib/ruby-prof/method_info.rb +111 -0
- data/lib/ruby-prof/symbol_to_proc.rb +8 -0
- data/lib/ruby-prof/task.rb +146 -0
- data/lib/ruby-prof/test.rb +148 -0
- data/lib/unprof.rb +8 -0
- data/rails/environment/profile.rb +24 -0
- data/rails/example/example_test.rb +9 -0
- data/rails/profile_test_helper.rb +21 -0
- data/test/aggregate_test.rb +121 -0
- data/test/basic_test.rb +290 -0
- data/test/current_failures_windows +8 -0
- data/test/do_nothing.rb +0 -0
- data/test/duplicate_names_test.rb +32 -0
- data/test/enumerable_test.rb +16 -0
- data/test/exceptions_test.rb +15 -0
- data/test/exclude_threads_test.rb +54 -0
- data/test/exec_test.rb +14 -0
- data/test/line_number_test.rb +73 -0
- data/test/measurement_test.rb +121 -0
- data/test/module_test.rb +54 -0
- data/test/no_method_class_test.rb +13 -0
- data/test/prime.rb +58 -0
- data/test/prime_test.rb +13 -0
- data/test/printers_test.rb +130 -0
- data/test/recursive_test.rb +275 -0
- data/test/ruby-prof-bin +20 -0
- data/test/singleton_test.rb +37 -0
- data/test/stack_test.rb +138 -0
- data/test/start_stop_test.rb +95 -0
- data/test/test_suite.rb +23 -0
- data/test/thread_test.rb +173 -0
- data/test/unique_call_path_test.rb +225 -0
- metadata +143 -0
data/test/do_nothing.rb
ADDED
File without changes
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'ruby-prof'
|
5
|
+
|
6
|
+
class DuplicateNames < Test::Unit::TestCase
|
7
|
+
def test_names
|
8
|
+
result = RubyProf::profile do
|
9
|
+
str = %{module Foo; class Bar; def foo; end end end}
|
10
|
+
|
11
|
+
eval str
|
12
|
+
Foo::Bar.new.foo
|
13
|
+
DuplicateNames.class_eval {remove_const :Foo}
|
14
|
+
|
15
|
+
eval str
|
16
|
+
Foo::Bar.new.foo
|
17
|
+
DuplicateNames.class_eval {remove_const :Foo}
|
18
|
+
|
19
|
+
eval str
|
20
|
+
Foo::Bar.new.foo
|
21
|
+
end
|
22
|
+
|
23
|
+
# There should be 3 foo methods
|
24
|
+
methods = result.threads.values.first.sort.reverse
|
25
|
+
|
26
|
+
methods = methods.select do |method|
|
27
|
+
method.full_name == 'DuplicateNames::Foo::Bar#foo'
|
28
|
+
end
|
29
|
+
|
30
|
+
assert_equal(3, methods.length)
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'ruby-prof'
|
5
|
+
|
6
|
+
# -- Test for bug
|
7
|
+
# http://github.com/rdp/ruby-prof/issues#issue/12
|
8
|
+
|
9
|
+
class EnumerableTest < Test::Unit::TestCase
|
10
|
+
def test_enumerable
|
11
|
+
result = RubyProf.profile do
|
12
|
+
3.times { [1,2,3].any? {|n| n} }
|
13
|
+
end
|
14
|
+
assert result.threads.to_a.first[1].length == 4
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'test/unit'
|
3
|
+
require 'ruby-prof'
|
4
|
+
|
5
|
+
class ExceptionsTest < Test::Unit::TestCase
|
6
|
+
def test_profile
|
7
|
+
result = begin
|
8
|
+
RubyProf.profile do
|
9
|
+
raise(RuntimeError, 'Test error')
|
10
|
+
end
|
11
|
+
rescue => e
|
12
|
+
end
|
13
|
+
assert_not_nil(result)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'ruby-prof'
|
5
|
+
|
6
|
+
|
7
|
+
# -- Tests ----
|
8
|
+
class ExcludeThreadsTest < Test::Unit::TestCase
|
9
|
+
def test_exclude_threads
|
10
|
+
|
11
|
+
def thread1_proc
|
12
|
+
sleep(0.5)
|
13
|
+
sleep(2)
|
14
|
+
end
|
15
|
+
|
16
|
+
def thread2_proc
|
17
|
+
sleep(0.5)
|
18
|
+
sleep(2)
|
19
|
+
end
|
20
|
+
|
21
|
+
thread1 = Thread.new do
|
22
|
+
thread1_proc
|
23
|
+
end
|
24
|
+
|
25
|
+
thread2 = Thread.new do
|
26
|
+
thread2_proc
|
27
|
+
end
|
28
|
+
|
29
|
+
RubyProf::exclude_threads = [ thread2 ]
|
30
|
+
|
31
|
+
RubyProf.start
|
32
|
+
|
33
|
+
thread1.join
|
34
|
+
thread2.join
|
35
|
+
|
36
|
+
result = RubyProf.stop
|
37
|
+
|
38
|
+
RubyProf::exclude_threads = nil
|
39
|
+
|
40
|
+
assert_equal(2, result.threads.length)
|
41
|
+
|
42
|
+
output = Array.new
|
43
|
+
result.threads.each do | thread_id, methods |
|
44
|
+
methods.each do | m |
|
45
|
+
if m.full_name.index("ExcludeThreadsTest#thread") == 0
|
46
|
+
output.push(m.full_name)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
assert_equal(1, output.length)
|
52
|
+
assert_equal("ExcludeThreadsTest#thread1_proc", output[0])
|
53
|
+
end
|
54
|
+
end
|
data/test/exec_test.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'os'
|
5
|
+
|
6
|
+
# -- Test for bug when it loads with no frames
|
7
|
+
|
8
|
+
class EnumerableTest < Test::Unit::TestCase
|
9
|
+
def test_being_able_to_run_its_binary
|
10
|
+
Dir.chdir(File.dirname(__FILE__)) do
|
11
|
+
assert system(OS.ruby_bin + " ruby-prof-bin do_nothing.rb")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'test/unit'
|
3
|
+
require 'ruby-prof'
|
4
|
+
require 'prime'
|
5
|
+
|
6
|
+
class LineNumbers
|
7
|
+
def method1
|
8
|
+
a = 3
|
9
|
+
end
|
10
|
+
|
11
|
+
def method2
|
12
|
+
a = 3
|
13
|
+
method1
|
14
|
+
end
|
15
|
+
|
16
|
+
def method3
|
17
|
+
sleep(1)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# -- Tests ----
|
22
|
+
class LineNumbersTest < Test::Unit::TestCase
|
23
|
+
def test_function_line_no
|
24
|
+
numbers = LineNumbers.new
|
25
|
+
|
26
|
+
result = RubyProf.profile do
|
27
|
+
numbers.method2
|
28
|
+
end
|
29
|
+
|
30
|
+
methods = result.threads.values.first.sort.reverse
|
31
|
+
assert_equal(3, methods.length)
|
32
|
+
|
33
|
+
method = methods[0]
|
34
|
+
assert_equal('LineNumbersTest#test_function_line_no', method.full_name)
|
35
|
+
assert_equal(27, method.line)
|
36
|
+
|
37
|
+
method = methods[1]
|
38
|
+
assert_equal('LineNumbers#method2', method.full_name)
|
39
|
+
assert_equal(11, method.line)
|
40
|
+
|
41
|
+
method = methods[2]
|
42
|
+
assert_equal('LineNumbers#method1', method.full_name)
|
43
|
+
assert_equal(7, method.line)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_c_function
|
47
|
+
numbers = LineNumbers.new
|
48
|
+
|
49
|
+
result = RubyProf.profile do
|
50
|
+
numbers.method3
|
51
|
+
end
|
52
|
+
|
53
|
+
methods = result.threads.values.first.sort_by {|method| method.full_name}
|
54
|
+
assert_equal(3, methods.length)
|
55
|
+
|
56
|
+
# Methods:
|
57
|
+
# LineNumbers#method3
|
58
|
+
# LineNumbersTest#test_c_function
|
59
|
+
# Kernel#sleep
|
60
|
+
|
61
|
+
method = methods[0]
|
62
|
+
assert_equal('Kernel#sleep', method.full_name)
|
63
|
+
assert_equal(0, method.line)
|
64
|
+
|
65
|
+
method = methods[1]
|
66
|
+
assert_equal('LineNumbers#method3', method.full_name)
|
67
|
+
assert_equal(16, method.line)
|
68
|
+
|
69
|
+
method = methods[2]
|
70
|
+
assert_equal('LineNumbersTest#test_c_function', method.full_name)
|
71
|
+
assert_equal(50, method.line)
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'test/unit'
|
3
|
+
require 'ruby-prof'
|
4
|
+
|
5
|
+
class MeasurementTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
GC.enable_stats if GC.respond_to?(:enable_stats)
|
8
|
+
end
|
9
|
+
|
10
|
+
def teardown
|
11
|
+
GC.disable_stats if GC.respond_to?(:disable_stats)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_process_time_mode
|
15
|
+
RubyProf::measure_mode = RubyProf::PROCESS_TIME
|
16
|
+
assert_equal(RubyProf::PROCESS_TIME, RubyProf::measure_mode)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_process_time
|
20
|
+
t = RubyProf.measure_process_time
|
21
|
+
assert_kind_of(Float, t)
|
22
|
+
|
23
|
+
u = RubyProf.measure_process_time
|
24
|
+
assert(u >= t, [t, u].inspect)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_wall_time_mode
|
28
|
+
RubyProf::measure_mode = RubyProf::WALL_TIME
|
29
|
+
assert_equal(RubyProf::WALL_TIME, RubyProf::measure_mode)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_wall_time
|
33
|
+
t = RubyProf.measure_wall_time
|
34
|
+
assert_kind_of Float, t
|
35
|
+
|
36
|
+
u = RubyProf.measure_wall_time
|
37
|
+
assert u >= t, [t, u].inspect
|
38
|
+
end
|
39
|
+
|
40
|
+
if RubyProf::CPU_TIME
|
41
|
+
def test_cpu_time_mode
|
42
|
+
RubyProf::measure_mode = RubyProf::CPU_TIME
|
43
|
+
assert_equal(RubyProf::CPU_TIME, RubyProf::measure_mode)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_cpu_time
|
47
|
+
RubyProf.cpu_frequency = 2.33e9
|
48
|
+
|
49
|
+
t = RubyProf.measure_cpu_time
|
50
|
+
assert_kind_of Float, t
|
51
|
+
|
52
|
+
u = RubyProf.measure_cpu_time
|
53
|
+
assert u > t, [t, u].inspect
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
if RubyProf::ALLOCATIONS
|
58
|
+
def test_allocations_mode
|
59
|
+
RubyProf::measure_mode = RubyProf::ALLOCATIONS
|
60
|
+
assert_equal(RubyProf::ALLOCATIONS, RubyProf::measure_mode)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_allocations
|
64
|
+
t = RubyProf.measure_allocations
|
65
|
+
assert_kind_of Integer, t
|
66
|
+
|
67
|
+
u = RubyProf.measure_allocations
|
68
|
+
assert u > t, [t, u].inspect
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
if RubyProf::MEMORY
|
73
|
+
def test_memory_mode
|
74
|
+
RubyProf::measure_mode = RubyProf::MEMORY
|
75
|
+
assert_equal(RubyProf::MEMORY, RubyProf::measure_mode)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_memory
|
79
|
+
t = RubyProf.measure_memory
|
80
|
+
assert_kind_of Integer, t
|
81
|
+
|
82
|
+
u = RubyProf.measure_memory
|
83
|
+
assert(u >= t, [t, u].inspect)
|
84
|
+
|
85
|
+
result = RubyProf.profile {Array.new}
|
86
|
+
total = result.threads.values.first.methods.inject(0) { |sum, m| sum + m.total_time }
|
87
|
+
|
88
|
+
assert(total > 0, 'Should measure more than zero kilobytes of memory usage')
|
89
|
+
assert_not_equal(0, total % 1, 'Should not truncate fractional kilobyte measurements')
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
if RubyProf::GC_RUNS
|
94
|
+
def test_gc_runs_mode
|
95
|
+
RubyProf::measure_mode = RubyProf::GC_RUNS
|
96
|
+
assert_equal(RubyProf::GC_RUNS, RubyProf::measure_mode)
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_gc_runs
|
100
|
+
t = RubyProf.measure_gc_runs
|
101
|
+
assert_kind_of Integer, t
|
102
|
+
|
103
|
+
GC.start
|
104
|
+
|
105
|
+
u = RubyProf.measure_gc_runs
|
106
|
+
assert u > t, [t, u].inspect
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
if RubyProf::GC_TIME
|
111
|
+
def test_gc_time
|
112
|
+
t = RubyProf.measure_gc_time
|
113
|
+
assert_kind_of Integer, t
|
114
|
+
|
115
|
+
GC.start
|
116
|
+
|
117
|
+
u = RubyProf.measure_gc_time
|
118
|
+
assert u > t, [t, u].inspect
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
data/test/module_test.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'test/unit'
|
3
|
+
require 'ruby-prof'
|
4
|
+
|
5
|
+
# Need to use wall time for this test due to the sleep calls
|
6
|
+
RubyProf::measure_mode = RubyProf::WALL_TIME
|
7
|
+
|
8
|
+
module Foo
|
9
|
+
def Foo::hello
|
10
|
+
sleep(0.5)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module Bar
|
15
|
+
def Bar::hello
|
16
|
+
sleep(0.5)
|
17
|
+
Foo::hello
|
18
|
+
end
|
19
|
+
|
20
|
+
def hello
|
21
|
+
sleep(0.5)
|
22
|
+
Bar::hello
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
include Bar
|
27
|
+
|
28
|
+
class ModuleTest < Test::Unit::TestCase
|
29
|
+
def test_nested_modules
|
30
|
+
result = RubyProf.profile do
|
31
|
+
hello
|
32
|
+
end
|
33
|
+
|
34
|
+
methods = result.threads.values.first.sort.reverse
|
35
|
+
|
36
|
+
# Length should be 5
|
37
|
+
assert_equal(5, methods.length)
|
38
|
+
|
39
|
+
method = methods[0]
|
40
|
+
assert_equal('ModuleTest#test_nested_modules', method.full_name)
|
41
|
+
|
42
|
+
method = methods[1]
|
43
|
+
assert_equal('Bar#hello', method.full_name)
|
44
|
+
|
45
|
+
method = methods[2]
|
46
|
+
assert_equal('Kernel#sleep', method.full_name)
|
47
|
+
|
48
|
+
method = methods[3]
|
49
|
+
assert_equal('<Module::Bar>#hello', method.full_name)
|
50
|
+
|
51
|
+
method = methods[4]
|
52
|
+
assert_equal('<Module::Foo>#hello', method.full_name)
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'ruby-prof'
|
3
|
+
|
4
|
+
# Make sure this works with no class or method
|
5
|
+
result = RubyProf.profile do
|
6
|
+
sleep 1
|
7
|
+
end
|
8
|
+
|
9
|
+
methods = result.threads.values.first
|
10
|
+
global_method = methods.sort_by {|method| method.full_name}.first
|
11
|
+
if global_method.full_name != 'Global#[No method]'
|
12
|
+
raise(RuntimeError, "Wrong method name. Expected: Global#[No method]. Actual: #{global_method.full_name}")
|
13
|
+
end
|
data/test/prime.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# A silly little test program that finds prime numbers. It
|
2
|
+
# is intentionally badly designed to show off the use
|
3
|
+
# of ruby-prof.
|
4
|
+
#
|
5
|
+
# Source from http://people.cs.uchicago.edu/~bomb154/154/maclabs/profilers-lab/
|
6
|
+
|
7
|
+
def make_random_array(length, maxnum)
|
8
|
+
result = Array.new(length)
|
9
|
+
result.each_index do |i|
|
10
|
+
result[i] = rand(maxnum)
|
11
|
+
end
|
12
|
+
|
13
|
+
result
|
14
|
+
end
|
15
|
+
|
16
|
+
def is_prime(x)
|
17
|
+
y = 2
|
18
|
+
y.upto(x-1) do |i|
|
19
|
+
return false if (x % i) == 0
|
20
|
+
end
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
def find_primes(arr)
|
25
|
+
result = arr.select do |value|
|
26
|
+
is_prime(value)
|
27
|
+
end
|
28
|
+
result
|
29
|
+
end
|
30
|
+
|
31
|
+
def find_largest(primes)
|
32
|
+
largest = primes.first
|
33
|
+
|
34
|
+
# Intentionally use upto for example purposes
|
35
|
+
# (upto is also called from is_prime)
|
36
|
+
0.upto(primes.length-1) do |i|
|
37
|
+
sleep(0.02)
|
38
|
+
prime = primes[i]
|
39
|
+
if prime > largest
|
40
|
+
largest = prime
|
41
|
+
end
|
42
|
+
end
|
43
|
+
largest
|
44
|
+
end
|
45
|
+
|
46
|
+
def run_primes
|
47
|
+
length = 10
|
48
|
+
maxnum = 1000
|
49
|
+
|
50
|
+
# Create random numbers
|
51
|
+
random_array = make_random_array(length, maxnum)
|
52
|
+
|
53
|
+
# Find the primes
|
54
|
+
primes = find_primes(random_array)
|
55
|
+
|
56
|
+
# Find the largest primes
|
57
|
+
# largest = find_largest(primes)
|
58
|
+
end
|