1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
# encoding: utf-8
module RubyProf
# Generates graph[link:files/examples/graph_txt.html] profile reports as text.
# To use the graph printer:
#
# result = RubyProf.profile do
# [code to profile]
# end
#
# printer = RubyProf::GraphPrinter.new(result)
# printer.print(STDOUT, {})
#
# The constructor takes two arguments. See the README
class GraphPrinter < AbstractPrinter
PERCENTAGE_WIDTH = 8
TIME_WIDTH = 11
CALL_WIDTH = 17
private
def print_header(thread)
@output << "Measure Mode: %s\n" % RubyProf.measure_mode_string
@output << "Thread ID: #{thread.id}\n"
@output << "Fiber ID: #{thread.fiber_id}\n" unless thread.id == thread.fiber_id
@output << "Total Time: #{thread.total_time}\n"
@output << "Sort by: #{sort_method}\n"
@output << "\n"
# 1 is for % sign
@output << sprintf("%#{PERCENTAGE_WIDTH}s", "%total")
@output << sprintf("%#{PERCENTAGE_WIDTH}s", "%self")
@output << sprintf("%#{TIME_WIDTH}s", "total")
@output << sprintf("%#{TIME_WIDTH}s", "self")
@output << sprintf("%#{TIME_WIDTH}s", "wait")
@output << sprintf("%#{TIME_WIDTH}s", "child")
@output << sprintf("%#{CALL_WIDTH}s", "calls")
@output << " name"
@output << "\n"
end
def print_methods(thread)
total_time = thread.total_time
# Sort methods from longest to shortest total time
methods = thread.methods.sort_by(&sort_method)
# Print each method in total time order
methods.reverse_each do |method|
total_percentage = (method.total_time/total_time) * 100
next if total_percentage < min_percent
self_percentage = (method.self_time/total_time) * 100
@output << "-" * 80 << "\n"
print_parents(thread, method)
# 1 is for % sign
@output << sprintf("%#{PERCENTAGE_WIDTH-1}.2f\%", total_percentage)
@output << sprintf("%#{PERCENTAGE_WIDTH-1}.2f\%", self_percentage)
@output << sprintf("%#{TIME_WIDTH}.3f", method.total_time)
@output << sprintf("%#{TIME_WIDTH}.3f", method.self_time)
@output << sprintf("%#{TIME_WIDTH}.3f", method.wait_time)
@output << sprintf("%#{TIME_WIDTH}.3f", method.children_time)
@output << sprintf("%#{CALL_WIDTH}i", method.called)
@output << sprintf(" %s", method.recursive? ? "*" : " ")
@output << sprintf("%s", method_name(method))
if print_file
@output << sprintf(" %s:%s", method.source_file, method.line)
end
@output << "\n"
print_children(method)
end
end
def print_parents(thread, method)
method.aggregate_parents.sort_by(&:total_time).each do |caller|
next unless caller.parent
@output << " " * 2 * PERCENTAGE_WIDTH
@output << sprintf("%#{TIME_WIDTH}.3f", caller.total_time)
@output << sprintf("%#{TIME_WIDTH}.3f", caller.self_time)
@output << sprintf("%#{TIME_WIDTH}.3f", caller.wait_time)
@output << sprintf("%#{TIME_WIDTH}.3f", caller.children_time)
call_called = "#{caller.called}/#{method.called}"
@output << sprintf("%#{CALL_WIDTH}s", call_called)
@output << sprintf(" %s", caller.parent.target.full_name)
@output << "\n"
end
end
def print_children(method)
method.aggregate_children.sort_by(&:total_time).reverse.each do |child|
# Get children method
@output << " " * 2 * PERCENTAGE_WIDTH
@output << sprintf("%#{TIME_WIDTH}.3f", child.total_time)
@output << sprintf("%#{TIME_WIDTH}.3f", child.self_time)
@output << sprintf("%#{TIME_WIDTH}.3f", child.wait_time)
@output << sprintf("%#{TIME_WIDTH}.3f", child.children_time)
call_called = "#{child.called}/#{child.target.called}"
@output << sprintf("%#{CALL_WIDTH}s", call_called)
@output << sprintf(" %s", child.target.full_name)
@output << "\n"
end
end
def print_footer(thread)
@output << "\n"
@output << "* indicates recursively called methods\n"
end
end
end
|