ruby-prof 0.13.1 → 1.4.2
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.
- checksums.yaml +5 -5
- data/CHANGES +579 -371
- data/LICENSE +24 -23
- data/README.rdoc +5 -433
- data/Rakefile +98 -110
- data/bin/ruby-prof +328 -329
- data/bin/ruby-prof-check-trace +45 -0
- data/ext/ruby_prof/extconf.rb +16 -59
- data/ext/ruby_prof/rp_aggregate_call_tree.c +59 -0
- data/ext/ruby_prof/rp_aggregate_call_tree.h +13 -0
- data/ext/ruby_prof/rp_allocation.c +287 -0
- data/ext/ruby_prof/rp_allocation.h +31 -0
- data/ext/ruby_prof/rp_call_tree.c +369 -0
- data/ext/ruby_prof/rp_call_tree.h +43 -0
- data/ext/ruby_prof/rp_call_trees.c +288 -0
- data/ext/ruby_prof/rp_call_trees.h +28 -0
- data/ext/ruby_prof/rp_measure_allocations.c +50 -65
- data/ext/ruby_prof/rp_measure_memory.c +42 -73
- data/ext/ruby_prof/rp_measure_process_time.c +65 -71
- data/ext/ruby_prof/rp_measure_wall_time.c +64 -42
- data/ext/ruby_prof/rp_measurement.c +237 -0
- data/ext/ruby_prof/rp_measurement.h +50 -0
- data/ext/ruby_prof/rp_method.c +491 -420
- data/ext/ruby_prof/rp_method.h +62 -57
- data/ext/ruby_prof/rp_profile.c +908 -0
- data/ext/ruby_prof/rp_profile.h +35 -0
- data/ext/ruby_prof/rp_stack.c +212 -128
- data/ext/ruby_prof/rp_stack.h +53 -51
- data/ext/ruby_prof/rp_thread.c +362 -268
- data/ext/ruby_prof/rp_thread.h +39 -27
- data/ext/ruby_prof/ruby_prof.c +52 -695
- data/ext/ruby_prof/ruby_prof.h +26 -55
- data/ext/ruby_prof/vc/ruby_prof.sln +28 -21
- data/ext/ruby_prof/vc/{ruby_prof_20.vcxproj → ruby_prof.vcxproj} +56 -8
- data/lib/ruby-prof.rb +52 -67
- data/lib/ruby-prof/assets/call_stack_printer.html.erb +710 -0
- data/lib/ruby-prof/assets/call_stack_printer.png +0 -0
- data/lib/ruby-prof/assets/graph_printer.html.erb +355 -0
- data/lib/ruby-prof/call_tree.rb +57 -0
- data/lib/ruby-prof/call_tree_visitor.rb +36 -0
- data/lib/ruby-prof/compatibility.rb +99 -169
- data/lib/ruby-prof/exclude_common_methods.rb +198 -0
- data/lib/ruby-prof/measurement.rb +17 -0
- data/lib/ruby-prof/method_info.rb +78 -131
- data/lib/ruby-prof/printers/abstract_printer.rb +137 -85
- data/lib/ruby-prof/printers/call_info_printer.rb +53 -41
- data/lib/ruby-prof/printers/call_stack_printer.rb +180 -773
- data/lib/ruby-prof/printers/call_tree_printer.rb +151 -92
- data/lib/ruby-prof/printers/dot_printer.rb +132 -132
- data/lib/ruby-prof/printers/flat_printer.rb +53 -69
- data/lib/ruby-prof/printers/graph_html_printer.rb +63 -255
- data/lib/ruby-prof/printers/graph_printer.rb +113 -116
- data/lib/ruby-prof/printers/multi_printer.rb +127 -56
- data/lib/ruby-prof/profile.rb +37 -77
- data/lib/ruby-prof/rack.rb +62 -15
- data/lib/ruby-prof/task.rb +147 -147
- data/lib/ruby-prof/thread.rb +10 -12
- data/lib/ruby-prof/version.rb +3 -0
- data/lib/unprof.rb +10 -10
- data/ruby-prof.gemspec +65 -61
- data/test/abstract_printer_test.rb +26 -0
- data/test/alias_test.rb +126 -0
- data/test/basic_test.rb +43 -128
- data/test/call_tree_visitor_test.rb +32 -0
- data/test/call_trees_test.rb +66 -0
- data/test/duplicate_names_test.rb +32 -32
- data/test/dynamic_method_test.rb +53 -74
- data/test/enumerable_test.rb +21 -16
- data/test/exceptions_test.rb +24 -16
- data/test/exclude_methods_test.rb +151 -0
- data/test/exclude_threads_test.rb +53 -54
- data/test/fiber_test.rb +129 -65
- data/test/gc_test.rb +90 -0
- data/test/inverse_call_tree_test.rb +175 -0
- data/test/line_number_test.rb +158 -71
- data/test/marshal_test.rb +113 -0
- data/test/measure_allocations.rb +30 -0
- data/test/measure_allocations_test.rb +375 -25
- data/test/measure_allocations_trace_test.rb +375 -0
- data/test/measure_memory_trace_test.rb +1101 -0
- data/test/measure_process_time_test.rb +785 -62
- data/test/measure_times.rb +56 -0
- data/test/measure_wall_time_test.rb +434 -254
- data/test/multi_printer_test.rb +71 -82
- data/test/no_method_class_test.rb +15 -15
- data/test/pause_resume_test.rb +175 -166
- data/test/prime.rb +54 -54
- data/test/prime_script.rb +6 -0
- data/test/printer_call_stack_test.rb +27 -0
- data/test/printer_call_tree_test.rb +30 -0
- data/test/printer_flat_test.rb +99 -0
- data/test/printer_graph_html_test.rb +59 -0
- data/test/printer_graph_test.rb +40 -0
- data/test/printers_test.rb +141 -257
- data/test/printing_recursive_graph_test.rb +81 -0
- data/test/profile_test.rb +16 -0
- data/test/rack_test.rb +93 -0
- data/test/recursive_test.rb +206 -215
- data/test/singleton_test.rb +38 -38
- data/test/stack_printer_test.rb +64 -78
- data/test/start_stop_test.rb +109 -112
- data/test/test_helper.rb +13 -115
- data/test/thread_test.rb +144 -178
- data/test/unique_call_path_test.rb +120 -224
- data/test/yarv_test.rb +56 -0
- metadata +77 -133
- data/doc/LICENSE.html +0 -155
- data/doc/README_rdoc.html +0 -648
- data/doc/Rack.html +0 -167
- data/doc/Rack/RubyProf.html +0 -319
- data/doc/RubyProf.html +0 -1000
- data/doc/RubyProf/AbstractPrinter.html +0 -580
- data/doc/RubyProf/AggregateCallInfo.html +0 -570
- data/doc/RubyProf/CallInfo.html +0 -512
- data/doc/RubyProf/CallInfoPrinter.html +0 -190
- data/doc/RubyProf/CallInfoVisitor.html +0 -332
- data/doc/RubyProf/CallStackPrinter.html +0 -1600
- data/doc/RubyProf/CallTreePrinter.html +0 -413
- data/doc/RubyProf/Cmd.html +0 -669
- data/doc/RubyProf/DotPrinter.html +0 -312
- data/doc/RubyProf/FlatPrinter.html +0 -229
- data/doc/RubyProf/FlatPrinterWithLineNumbers.html +0 -267
- data/doc/RubyProf/GraphHtmlPrinter.html +0 -630
- data/doc/RubyProf/GraphPrinter.html +0 -209
- data/doc/RubyProf/MethodInfo.html +0 -713
- data/doc/RubyProf/MultiPrinter.html +0 -407
- data/doc/RubyProf/Profile.html +0 -821
- data/doc/RubyProf/ProfileTask.html +0 -532
- data/doc/RubyProf/Test.html +0 -578
- data/doc/RubyProf/Thread.html +0 -262
- data/doc/created.rid +0 -32
- data/doc/examples/flat_txt.html +0 -191
- data/doc/examples/graph_txt.html +0 -305
- data/doc/images/add.png +0 -0
- data/doc/images/brick.png +0 -0
- data/doc/images/brick_link.png +0 -0
- data/doc/images/bug.png +0 -0
- data/doc/images/bullet_black.png +0 -0
- data/doc/images/bullet_toggle_minus.png +0 -0
- data/doc/images/bullet_toggle_plus.png +0 -0
- data/doc/images/date.png +0 -0
- data/doc/images/delete.png +0 -0
- data/doc/images/find.png +0 -0
- data/doc/images/loadingAnimation.gif +0 -0
- data/doc/images/macFFBgHack.png +0 -0
- data/doc/images/package.png +0 -0
- data/doc/images/page_green.png +0 -0
- data/doc/images/page_white_text.png +0 -0
- data/doc/images/page_white_width.png +0 -0
- data/doc/images/plugin.png +0 -0
- data/doc/images/ruby.png +0 -0
- data/doc/images/tag_blue.png +0 -0
- data/doc/images/tag_green.png +0 -0
- data/doc/images/transparent.png +0 -0
- data/doc/images/wrench.png +0 -0
- data/doc/images/wrench_orange.png +0 -0
- data/doc/images/zoom.png +0 -0
- data/doc/index.html +0 -647
- data/doc/js/darkfish.js +0 -155
- data/doc/js/jquery.js +0 -18
- data/doc/js/navigation.js +0 -142
- data/doc/js/search.js +0 -94
- data/doc/js/search_index.js +0 -1
- data/doc/js/searcher.js +0 -228
- data/doc/rdoc.css +0 -543
- data/doc/table_of_contents.html +0 -462
- data/examples/empty.png +0 -0
- data/examples/flat.txt +0 -55
- data/examples/graph.dot +0 -106
- data/examples/graph.html +0 -823
- data/examples/graph.png +0 -0
- data/examples/graph.txt +0 -170
- data/examples/minus.png +0 -0
- data/examples/multi.flat.txt +0 -23
- data/examples/multi.graph.html +0 -906
- data/examples/multi.grind.dat +0 -194
- data/examples/multi.stack.html +0 -573
- data/examples/plus.png +0 -0
- data/examples/stack.html +0 -573
- data/ext/ruby_prof/rp_call_info.c +0 -407
- data/ext/ruby_prof/rp_call_info.h +0 -48
- data/ext/ruby_prof/rp_measure.c +0 -48
- data/ext/ruby_prof/rp_measure.h +0 -45
- data/ext/ruby_prof/rp_measure_cpu_time.c +0 -112
- data/ext/ruby_prof/rp_measure_gc_runs.c +0 -65
- data/ext/ruby_prof/rp_measure_gc_time.c +0 -57
- data/ext/ruby_prof/vc/ruby_prof_18.vcxproj +0 -108
- data/ext/ruby_prof/vc/ruby_prof_19.vcxproj +0 -110
- data/ext/ruby_prof/version.h +0 -7
- data/lib/ruby-prof/aggregate_call_info.rb +0 -72
- data/lib/ruby-prof/call_info.rb +0 -89
- data/lib/ruby-prof/call_info_visitor.rb +0 -44
- data/lib/ruby-prof/images/empty.png +0 -0
- data/lib/ruby-prof/images/minus.png +0 -0
- data/lib/ruby-prof/images/plus.png +0 -0
- data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +0 -57
- data/lib/ruby-prof/test.rb +0 -150
- data/test/aggregate_test.rb +0 -136
- data/test/call_info_test.rb +0 -78
- data/test/call_info_visitor_test.rb +0 -31
- data/test/exec_test.rb +0 -14
- data/test/measure_cpu_time_test.rb +0 -220
- data/test/measure_gc_runs_test.rb +0 -32
- data/test/measure_gc_time_test.rb +0 -36
- data/test/measure_memory_test.rb +0 -31
- data/test/method_elimination_test.rb +0 -84
- data/test/module_test.rb +0 -45
- data/test/stack_test.rb +0 -138
- data/test/test_suite.rb +0 -37
data/ext/ruby_prof/version.h
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
/* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
|
2
|
-
Please see the LICENSE file for copyright and distribution information */
|
3
|
-
|
4
|
-
#define RUBY_PROF_VERSION "0.13.1" // as a string, for easy parsing from rake files
|
5
|
-
#define RUBY_PROF_VERSION_MAJ 0
|
6
|
-
#define RUBY_PROF_VERSION_MIN 13
|
7
|
-
#define RUBY_PROF_VERSION_MIC 1
|
@@ -1,72 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module RubyProf
|
4
|
-
class AggregateCallInfo
|
5
|
-
attr_reader :call_infos
|
6
|
-
|
7
|
-
def initialize(call_infos)
|
8
|
-
if call_infos.length == 0
|
9
|
-
raise(ArgumentError, "Must specify at least one call info.")
|
10
|
-
end
|
11
|
-
@call_infos = call_infos
|
12
|
-
end
|
13
|
-
|
14
|
-
def target
|
15
|
-
call_infos.first.target
|
16
|
-
end
|
17
|
-
|
18
|
-
def parent
|
19
|
-
call_infos.first.parent
|
20
|
-
end
|
21
|
-
|
22
|
-
def line
|
23
|
-
call_infos.first.line
|
24
|
-
end
|
25
|
-
|
26
|
-
def children
|
27
|
-
call_infos.inject(Array.new) do |result, call_info|
|
28
|
-
result.concat(call_info.children)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def total_time
|
33
|
-
aggregate_without_recursion(:total_time)
|
34
|
-
end
|
35
|
-
|
36
|
-
def self_time
|
37
|
-
aggregate_without_recursion(:self_time)
|
38
|
-
end
|
39
|
-
|
40
|
-
def wait_time
|
41
|
-
aggregate_without_recursion(:wait_time)
|
42
|
-
end
|
43
|
-
|
44
|
-
def children_time
|
45
|
-
aggregate_without_recursion(:children_time)
|
46
|
-
end
|
47
|
-
|
48
|
-
def called
|
49
|
-
aggregate(:called)
|
50
|
-
end
|
51
|
-
|
52
|
-
def to_s
|
53
|
-
"#{call_infos.first.target.full_name}"
|
54
|
-
end
|
55
|
-
|
56
|
-
private
|
57
|
-
|
58
|
-
def aggregate(method_name)
|
59
|
-
self.call_infos.inject(0) do |sum, call_info|
|
60
|
-
sum += call_info.send(method_name)
|
61
|
-
sum
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def aggregate_without_recursion(method_name)
|
66
|
-
self.call_infos.inject(0) do |sum, call_info|
|
67
|
-
sum += call_info.send(method_name) unless call_info.recursive
|
68
|
-
sum
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
data/lib/ruby-prof/call_info.rb
DELETED
@@ -1,89 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module RubyProf
|
4
|
-
class CallInfo
|
5
|
-
attr_accessor :recursive
|
6
|
-
|
7
|
-
def children_time
|
8
|
-
children.inject(0) do |sum, call_info|
|
9
|
-
sum += call_info.total_time
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def stack
|
14
|
-
@stack ||= begin
|
15
|
-
methods = Array.new
|
16
|
-
call_info = self
|
17
|
-
|
18
|
-
while call_info
|
19
|
-
methods << call_info.target
|
20
|
-
call_info = call_info.parent
|
21
|
-
end
|
22
|
-
methods.reverse
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def call_sequence
|
27
|
-
@call_sequence ||= begin
|
28
|
-
stack.map {|method| method.full_name}.join('->')
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def root?
|
33
|
-
self.parent.nil?
|
34
|
-
end
|
35
|
-
|
36
|
-
def to_s
|
37
|
-
"#{self.target.full_name} (c: #{self.called}, tt: #{self.total_time}, st: #{self.self_time}, ct: #{self.children_time})"
|
38
|
-
end
|
39
|
-
|
40
|
-
# eliminate call info from the call tree.
|
41
|
-
# adds self and wait time to parent and attaches called methods to parent.
|
42
|
-
# merges call trees for methods called from both praent end self.
|
43
|
-
def eliminate!
|
44
|
-
# puts "eliminating #{self}"
|
45
|
-
return unless parent
|
46
|
-
parent.add_self_time(self)
|
47
|
-
parent.add_wait_time(self)
|
48
|
-
children.each do |kid|
|
49
|
-
if call = parent.find_call(kid)
|
50
|
-
call.merge_call_tree(kid)
|
51
|
-
else
|
52
|
-
parent.children << kid
|
53
|
-
# $stderr.puts "setting parent of #{kid}\nto #{parent}"
|
54
|
-
kid.parent = parent
|
55
|
-
end
|
56
|
-
end
|
57
|
-
parent.children.delete(self)
|
58
|
-
end
|
59
|
-
|
60
|
-
# find a specific call in list of children. returns nil if not found.
|
61
|
-
# note: there can't be more than one child with a given target method. in other words:
|
62
|
-
# x.children.grep{|y|y.target==m}.size <= 1 for all method infos m and call infos x
|
63
|
-
def find_call(other)
|
64
|
-
matching = children.select { |kid| kid.target == other.target }
|
65
|
-
raise "inconsistent call tree" unless matching.size <= 1
|
66
|
-
matching.first
|
67
|
-
end
|
68
|
-
|
69
|
-
# merge two call trees. adds self, wait, and total time of other to self and merges children of other into children of self.
|
70
|
-
def merge_call_tree(other)
|
71
|
-
# $stderr.puts "merging #{self}\nand #{other}"
|
72
|
-
self.called += other.called
|
73
|
-
add_self_time(other)
|
74
|
-
add_wait_time(other)
|
75
|
-
add_total_time(other)
|
76
|
-
other.children.each do |other_kid|
|
77
|
-
if kid = find_call(other_kid)
|
78
|
-
# $stderr.puts "merging kids"
|
79
|
-
kid.merge_call_tree(other_kid)
|
80
|
-
else
|
81
|
-
other_kid.parent = self
|
82
|
-
children << other_kid
|
83
|
-
end
|
84
|
-
end
|
85
|
-
other.children.clear
|
86
|
-
other.target.call_infos.delete(other)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
# The call info visitor class does a depth-first traversal
|
2
|
-
# across a thread's call stack. At each call_info node,
|
3
|
-
# the visitor executes the block provided in the
|
4
|
-
# #visit method. The block is passed two parameters, the
|
5
|
-
# event and the call_info instance. Event will be
|
6
|
-
# either :enter or :exit.
|
7
|
-
#
|
8
|
-
# visitor = RubyProf::CallInfoVisitor.new(result.threads.first)
|
9
|
-
#
|
10
|
-
# method_names = Array.new
|
11
|
-
#
|
12
|
-
# visitor.visit do |call_info, event|
|
13
|
-
# method_names << call_info.target.full_name if event == :enter
|
14
|
-
# end
|
15
|
-
#
|
16
|
-
# puts method_names
|
17
|
-
|
18
|
-
module RubyProf
|
19
|
-
class CallInfoVisitor
|
20
|
-
attr_reader :block, :thread
|
21
|
-
|
22
|
-
def initialize(thread)
|
23
|
-
@thread = thread
|
24
|
-
end
|
25
|
-
|
26
|
-
def visit(&block)
|
27
|
-
@block = block
|
28
|
-
|
29
|
-
self.thread.top_methods.each do |method_info|
|
30
|
-
method_info.call_infos.each do |call_info|
|
31
|
-
self.visit_call_info(call_info)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def visit_call_info(call_info)
|
37
|
-
self.block.call(call_info, :enter)
|
38
|
-
call_info.children.each do |child|
|
39
|
-
visit_call_info(child)
|
40
|
-
end
|
41
|
-
self.block.call(call_info, :exit)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
Binary file
|
Binary file
|
Binary file
|
@@ -1,57 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module RubyProf
|
4
|
-
# Generates flat[link:files/examples/flat_txt.html] profile reports as text.
|
5
|
-
# To use the flat printer with line numbers:
|
6
|
-
#
|
7
|
-
# result = RubyProf.profile do
|
8
|
-
# [code to profile]
|
9
|
-
# end
|
10
|
-
#
|
11
|
-
# printer = RubyProf::FlatPrinterWithLineNumbers.new(result)
|
12
|
-
# printer.print(STDOUT, {})
|
13
|
-
#
|
14
|
-
class FlatPrinterWithLineNumbers < FlatPrinter
|
15
|
-
def print_methods(thread)
|
16
|
-
total_time = thread.total_time
|
17
|
-
|
18
|
-
methods = thread.methods.sort_by(&sort_method).reverse
|
19
|
-
sum = 0
|
20
|
-
methods.each do |method|
|
21
|
-
self_percent = (method.self_time / total_time) * 100
|
22
|
-
next if self_percent < min_percent
|
23
|
-
|
24
|
-
sum += method.self_time
|
25
|
-
#self_time_called = method.called > 0 ? method.self_time/method.called : 0
|
26
|
-
#total_time_called = method.called > 0? method.total_time/method.called : 0
|
27
|
-
|
28
|
-
@output << "%6.2f %9.3f %9.3f %9.3f %9.3f %8d %s%s \n" % [
|
29
|
-
method.self_time / total_time * 100, # %self
|
30
|
-
method.total_time, # total
|
31
|
-
method.self_time, # self
|
32
|
-
method.wait_time, # wait
|
33
|
-
method.children_time, # children
|
34
|
-
method.called, # calls
|
35
|
-
method.recursive? ? "*" : " ", # cycle
|
36
|
-
method_name(method) # name
|
37
|
-
]
|
38
|
-
if method.source_file != 'ruby_runtime'
|
39
|
-
@output << " %s:%s" % [File.expand_path(method.source_file), method.line]
|
40
|
-
end
|
41
|
-
@output << "\n\tcalled from: "
|
42
|
-
|
43
|
-
# make sure they're unique
|
44
|
-
method.call_infos.map{|ci|
|
45
|
-
if ci.parent && ci.parent.target.source_file != 'ruby_runtime'
|
46
|
-
[method_name(ci.parent.target), File.expand_path(ci.parent.target.source_file), ci.parent.target.line]
|
47
|
-
else
|
48
|
-
nil
|
49
|
-
end
|
50
|
-
}.compact.uniq.each{|args|
|
51
|
-
@output << " %s (%s:%s) " % args
|
52
|
-
}
|
53
|
-
@output << "\n\n"
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
data/lib/ruby-prof/test.rb
DELETED
@@ -1,150 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
# Now load ruby-prof and away we go
|
4
|
-
require 'fileutils'
|
5
|
-
require 'ruby-prof'
|
6
|
-
require 'benchmark'
|
7
|
-
|
8
|
-
module RubyProf
|
9
|
-
module Test
|
10
|
-
PROFILE_OPTIONS = {
|
11
|
-
:measure_modes => [RubyProf::PROCESS_TIME],
|
12
|
-
:count => 10,
|
13
|
-
:printers => [RubyProf::FlatPrinter, RubyProf::GraphHtmlPrinter],
|
14
|
-
:min_percent => 0.05,
|
15
|
-
:output_dir => Dir.pwd }
|
16
|
-
|
17
|
-
def output_dir
|
18
|
-
PROFILE_OPTIONS[:output_dir]
|
19
|
-
end
|
20
|
-
|
21
|
-
def run(result)
|
22
|
-
return if @method_name.to_s == "default_test"
|
23
|
-
|
24
|
-
yield(self.class::STARTED, name)
|
25
|
-
@_result = result
|
26
|
-
run_warmup
|
27
|
-
PROFILE_OPTIONS[:measure_modes].each do |measure_mode|
|
28
|
-
data = run_profile(measure_mode)
|
29
|
-
report_profile(data, measure_mode)
|
30
|
-
result.add_run
|
31
|
-
end
|
32
|
-
yield(self.class::FINISHED, name)
|
33
|
-
end
|
34
|
-
|
35
|
-
def run_test
|
36
|
-
begin
|
37
|
-
setup
|
38
|
-
yield
|
39
|
-
rescue ::Test::Unit::AssertionFailedError => e
|
40
|
-
add_failure(e.message, e.backtrace)
|
41
|
-
rescue StandardError, ScriptError
|
42
|
-
add_error($!)
|
43
|
-
ensure
|
44
|
-
begin
|
45
|
-
teardown
|
46
|
-
rescue ::Test::Unit::AssertionFailedError => e
|
47
|
-
add_failure(e.message, e.backtrace)
|
48
|
-
rescue StandardError, ScriptError
|
49
|
-
add_error($!)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def run_warmup
|
55
|
-
print "\n#{self.class.name}##{method_name}"
|
56
|
-
|
57
|
-
run_test do
|
58
|
-
bench = Benchmark.realtime do
|
59
|
-
__send__(@method_name)
|
60
|
-
end
|
61
|
-
puts " (%.2fs warmup)" % bench
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def run_profile(measure_mode)
|
66
|
-
RubyProf.measure_mode = measure_mode
|
67
|
-
|
68
|
-
print ' '
|
69
|
-
PROFILE_OPTIONS[:count].times do |i|
|
70
|
-
run_test do
|
71
|
-
begin
|
72
|
-
print '.'
|
73
|
-
$stdout.flush
|
74
|
-
GC.disable
|
75
|
-
|
76
|
-
RubyProf.resume do
|
77
|
-
__send__(@method_name)
|
78
|
-
end
|
79
|
-
ensure
|
80
|
-
GC.enable
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
data = RubyProf.stop
|
86
|
-
bench = data.threads.values.inject(0) do |total, method_infos|
|
87
|
-
top = method_infos.max
|
88
|
-
total += top.total_time
|
89
|
-
total
|
90
|
-
end
|
91
|
-
|
92
|
-
puts "\n #{measure_mode_name(measure_mode)}: #{format_profile_total(bench, measure_mode)}\n"
|
93
|
-
|
94
|
-
data
|
95
|
-
end
|
96
|
-
|
97
|
-
def format_profile_total(total, measure_mode)
|
98
|
-
case measure_mode
|
99
|
-
when RubyProf::PROCESS_TIME, RubyProf::WALL_TIME
|
100
|
-
"%.2f seconds" % total
|
101
|
-
when RubyProf::MEMORY
|
102
|
-
"%.2f kilobytes" % total
|
103
|
-
when RubyProf::ALLOCATIONS
|
104
|
-
"%d allocations" % total
|
105
|
-
else
|
106
|
-
"%.2f #{measure_mode}"
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def report_profile(data, measure_mode)
|
111
|
-
PROFILE_OPTIONS[:printers].each do |printer_klass|
|
112
|
-
printer = printer_klass.new(data)
|
113
|
-
|
114
|
-
# Makes sure the output directory exits
|
115
|
-
FileUtils.mkdir_p(output_dir)
|
116
|
-
|
117
|
-
# Open the file
|
118
|
-
file_name = report_filename(printer, measure_mode)
|
119
|
-
|
120
|
-
File.open(file_name, 'wb') do |file|
|
121
|
-
printer.print(file, PROFILE_OPTIONS)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
# The report filename is test_name + measure_mode + report_type
|
127
|
-
def report_filename(printer, measure_mode)
|
128
|
-
suffix =
|
129
|
-
case printer
|
130
|
-
when RubyProf::FlatPrinter; 'flat.txt'
|
131
|
-
when RubyProf::GraphPrinter; 'graph.txt'
|
132
|
-
when RubyProf::GraphHtmlPrinter; 'graph.html'
|
133
|
-
when RubyProf::CallTreePrinter; 'tree.txt'
|
134
|
-
else printer.to_s.downcase
|
135
|
-
end
|
136
|
-
|
137
|
-
"#{output_dir}/#{method_name}_#{measure_mode_name(measure_mode)}_#{suffix}"
|
138
|
-
end
|
139
|
-
|
140
|
-
def measure_mode_name(measure_mode)
|
141
|
-
case measure_mode
|
142
|
-
when RubyProf::PROCESS_TIME; 'process_time'
|
143
|
-
when RubyProf::WALL_TIME; 'wall_time'
|
144
|
-
when RubyProf::MEMORY; 'memory'
|
145
|
-
when RubyProf::ALLOCATIONS; 'allocations'
|
146
|
-
else "measure#{measure_mode}"
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
data/test/aggregate_test.rb
DELETED
@@ -1,136 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: UTF-8
|
3
|
-
|
4
|
-
require File.expand_path('../test_helper', __FILE__)
|
5
|
-
|
6
|
-
# Test data
|
7
|
-
# A B C
|
8
|
-
# | | |
|
9
|
-
# Z A A
|
10
|
-
# | |
|
11
|
-
# Z Z
|
12
|
-
|
13
|
-
class AggClass
|
14
|
-
def z
|
15
|
-
sleep 1
|
16
|
-
end
|
17
|
-
|
18
|
-
def a
|
19
|
-
z
|
20
|
-
end
|
21
|
-
|
22
|
-
def b
|
23
|
-
a
|
24
|
-
end
|
25
|
-
|
26
|
-
def c
|
27
|
-
a
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
class AggregateTest < Test::Unit::TestCase
|
32
|
-
def setup
|
33
|
-
# Need to use wall time for this test due to the sleep calls
|
34
|
-
RubyProf::measure_mode = RubyProf::WALL_TIME
|
35
|
-
end
|
36
|
-
|
37
|
-
def test_all_call_infos_are_not_recursive
|
38
|
-
c1 = AggClass.new
|
39
|
-
result = RubyProf.profile do
|
40
|
-
c1.a
|
41
|
-
c1.b
|
42
|
-
c1.c
|
43
|
-
end
|
44
|
-
methods = result.threads.first.methods.sort.reverse
|
45
|
-
methods.each do |m|
|
46
|
-
m.call_infos.each do |ci|
|
47
|
-
assert(!ci.recursive)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_call_infos
|
53
|
-
c1 = AggClass.new
|
54
|
-
result = RubyProf.profile do
|
55
|
-
c1.a
|
56
|
-
c1.b
|
57
|
-
c1.c
|
58
|
-
end
|
59
|
-
|
60
|
-
methods = result.threads.first.methods.sort.reverse
|
61
|
-
method = methods.find {|meth| meth.full_name == 'AggClass#z'}
|
62
|
-
|
63
|
-
# Check AggClass#z
|
64
|
-
assert_equal('AggClass#z', method.full_name)
|
65
|
-
assert_equal(3, method.called)
|
66
|
-
assert_in_delta(3, method.total_time, 0.05)
|
67
|
-
assert_in_delta(0, method.wait_time, 0.05)
|
68
|
-
assert_in_delta(0, method.self_time, 0.05)
|
69
|
-
assert_in_delta(3, method.children_time, 0.05)
|
70
|
-
assert_equal(3, method.call_infos.length)
|
71
|
-
|
72
|
-
call_info = method.call_infos[0]
|
73
|
-
assert_equal('AggregateTest#test_call_infos->AggClass#a->AggClass#z', call_info.call_sequence)
|
74
|
-
assert_equal(1, call_info.children.length)
|
75
|
-
|
76
|
-
call_info = method.call_infos[1]
|
77
|
-
assert_equal('AggregateTest#test_call_infos->AggClass#b->AggClass#a->AggClass#z', call_info.call_sequence)
|
78
|
-
assert_equal(1, call_info.children.length)
|
79
|
-
|
80
|
-
call_info = method.call_infos[2]
|
81
|
-
assert_equal('AggregateTest#test_call_infos->AggClass#c->AggClass#a->AggClass#z', call_info.call_sequence)
|
82
|
-
assert_equal(1, call_info.children.length)
|
83
|
-
end
|
84
|
-
|
85
|
-
def test_aggregates_parents
|
86
|
-
c1 = AggClass.new
|
87
|
-
result = RubyProf.profile do
|
88
|
-
c1.a
|
89
|
-
c1.b
|
90
|
-
c1.c
|
91
|
-
end
|
92
|
-
|
93
|
-
methods = result.threads.first.methods.sort.reverse
|
94
|
-
method = methods.find {|meth| meth.full_name == 'AggClass#z'}
|
95
|
-
|
96
|
-
# Check AggClass#z
|
97
|
-
assert_equal('AggClass#z', method.full_name)
|
98
|
-
|
99
|
-
call_infos = method.aggregate_parents
|
100
|
-
assert_equal(1, call_infos.length)
|
101
|
-
|
102
|
-
call_info = call_infos.first
|
103
|
-
assert_equal('AggClass#a', call_info.parent.target.full_name)
|
104
|
-
assert_in_delta(3, call_info.total_time, 0.05)
|
105
|
-
assert_in_delta(0, call_info.wait_time, 0.05)
|
106
|
-
assert_in_delta(0, call_info.self_time, 0.05)
|
107
|
-
assert_in_delta(3, call_info.children_time, 0.05)
|
108
|
-
assert_equal(3, call_info.called)
|
109
|
-
end
|
110
|
-
|
111
|
-
def test_aggregates_children
|
112
|
-
c1 = AggClass.new
|
113
|
-
result = RubyProf.profile do
|
114
|
-
c1.a
|
115
|
-
c1.b
|
116
|
-
c1.c
|
117
|
-
end
|
118
|
-
|
119
|
-
methods = result.threads.first.methods.sort.reverse
|
120
|
-
method = methods.find {|meth| meth.full_name == 'AggClass#a'}
|
121
|
-
|
122
|
-
# Check AggClass#a
|
123
|
-
assert_equal('AggClass#a', method.full_name)
|
124
|
-
|
125
|
-
call_infos = method.aggregate_children
|
126
|
-
assert_equal(1, call_infos.length)
|
127
|
-
|
128
|
-
call_info = call_infos.first
|
129
|
-
assert_equal('AggClass#z', call_info.target.full_name)
|
130
|
-
assert_in_delta(3, call_info.total_time, 0.05)
|
131
|
-
assert_in_delta(0, call_info.wait_time, 0.05)
|
132
|
-
assert_in_delta(0, call_info.self_time, 0.05)
|
133
|
-
assert_in_delta(3, call_info.children_time, 0.05)
|
134
|
-
assert_equal(3, call_info.called)
|
135
|
-
end
|
136
|
-
end
|