Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ruby-prof/ruby-prof
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: acunote/ruby-prof
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Can’t automatically merge. Don’t worry, you can still create the pull request.
  • 3 commits
  • 4 files changed
  • 2 contributors

Commits on Dec 2, 2010

  1. Implement two printers based on GraphPrinter and CallTreePrinter to g…

    …enerate
    
    non-aggregate calltree info in text or KCachegrind format.
    Sedinkin Alexandr committed Dec 2, 2010
    Copy the full SHA
    d95e057 View commit details

Commits on Aug 29, 2011

  1. Copy the full SHA
    f6f4cef View commit details
  2. Copy the full SHA
    85f85b7 View commit details
53 changes: 53 additions & 0 deletions lib/ruby-prof/call_tree_printer.rb
Original file line number Diff line number Diff line change
@@ -88,4 +88,57 @@ def print_methods(thread_id, methods)
end
end #end print_methods
end # end class

class CallTreePrinterWithoutAggregation < CallTreePrinter
def get_sequence_index(sequence)
@seq_cache ||= Hash.new
@seq_index ||= 1
sequence_array = sequence.split("->")
method_name = sequence_array.last
sequence = sequence_array.count>1 ? sequence_array[0..sequence_array.count - 2].join("->") : "root"
@seq_cache[method_name] = Hash.new unless @seq_cache.has_key?(method_name)
@seq_cache[method_name][sequence] = @seq_cache[method_name].keys.count+1 unless @seq_cache[method_name].include?(sequence)
@seq_cache[method_name][sequence]
end

def print_methods(thread_id, methods)
methods.reverse_each do |method|
parents = method.call_infos.map{|caller| caller if caller.parent}
children = method.children
call_tree = Hash.new
parents.each do |parent|
call_tree[parent] = Array.new
if parent
children.each do |child|
call_tree[parent] << child if child.call_sequence.include?(parent.call_sequence)
end
else
call_tree[parent] = children
end
end

call_tree.each do |parent, children|
# Print out the file and method name
@output << "fl=#{file(method)}\n"
@output << (parent ? "fn=#{method.full_name}(#{get_sequence_index(parent.call_sequence)})\n" : "fn=#{method.full_name}\n")

# Now print out the function line number and its self time
@output << "#{method.line} #{convert(method.self_time)}\n"

# Now print out all the children methods
children.each do |callee|
@output << "cfl=#{file(callee.target)}\n"
@output << "cfn=#{callee.target.full_name}(#{get_sequence_index(callee.call_sequence)})\n"
@output << "calls=#{callee.called} #{callee.line}\n"

# Print out total times here!
@output << "#{callee.line} #{convert(callee.total_time)}\n"
end
@output << "\n"
end
end
end #end print_methods

end #end class

end # end packages
58 changes: 58 additions & 0 deletions lib/ruby-prof/call_tree_printer_without_aggregation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@

module RubyProf
# Generate profiling information in calltree format
# for use by kcachegrind and similar tools.

class CallTreePrinterWithoutAggregation < CallTreePrinter
def get_sequence_index(sequence)
@seq_cache ||= Hash.new
@seq_index ||= 1
sequence_array = sequence.split("->")
method_name = sequence_array.last
sequence = sequence_array.count>1 ? sequence_array[0..sequence_array.count - 2].join("->") : "root"
@seq_cache[method_name] = Hash.new unless @seq_cache.has_key?(method_name)
@seq_cache[method_name][sequence] = @seq_cache[method_name].keys.count+1 unless @seq_cache[method_name].include?(sequence)
@seq_cache[method_name][sequence]
end

def print_methods(thread_id, methods)
methods.reverse_each do |method|
parents = method.call_infos.map{|caller| caller if caller.parent}
children = method.children
call_tree = Hash.new
parents.each do |parent|
call_tree[parent] = Array.new
if parent
children.each do |child|
call_tree[parent] << child if child.call_sequence.include?(parent.call_sequence)
end
else
call_tree[parent] = children
end
end

call_tree.each do |parent, children|
# Print out the file and method name
@output << "fl=#{file(method)}\n"
@output << (parent ? "fn=#{method.full_name}(#{get_sequence_index(parent.call_sequence)})\n" : "fn=#{method.full_name}\n")

# Now print out the function line number and its self time
@output << "#{method.line} #{convert(method.self_time)}\n"

# Now print out all the children methods
children.each do |callee|
@output << "cfl=#{file(callee.target)}\n"
@output << "cfn=#{callee.target.full_name}(#{get_sequence_index(callee.call_sequence)})\n"
@output << "calls=#{callee.called} #{callee.line}\n"

# Print out total times here!
@output << "#{callee.line} #{convert(callee.total_time)}\n"
end
@output << "\n"
end
end
end #end print_methods

end #end class

end # end packages
90 changes: 89 additions & 1 deletion lib/ruby-prof/graph_printer.rb
Original file line number Diff line number Diff line change
@@ -152,5 +152,93 @@ def print_children(method)
end
end
end
end

class GraphPrinterWithoutAggregation < GraphPrinter
private
def print_methods(thread_id, methods)
# Sort methods from longest to shortest total time
methods = methods.sort

toplevel = methods.last
total_time = toplevel.total_time
total_time = 0.01 if total_time == 0

print_heading(thread_id)

# Print each method in total time order
methods.reverse_each do |method|
total_percentage = (method.total_time/total_time) * 100
self_percentage = (method.self_time/total_time) * 100

next if total_percentage < min_percent

parents = method.call_infos.map{|caller| caller if caller.parent}
children = method.children
call_tree = Hash.new
parents.each do |parent|
call_tree[parent] = Array.new
if parent
children.each do |child|
call_tree[parent] << child if child.call_sequence.include?(parent.call_sequence)
end
else
call_tree[parent] = children
end
end

call_tree.each do |parent, children|
@output << "-" * 80 << "\n"
print_parent(parent, method) if parent

# 1 is for % sign
@output << sprintf("%#{PERCENTAGE_WIDTH-1}.2f\%", total_percentage)
@output << sprintf("%#{PERCENTAGE_WIDTH-1}.2f\%", self_percentage)
@output << sprintf("%#{TIME_WIDTH}.2f", method.total_time)
@output << sprintf("%#{TIME_WIDTH}.2f", method.self_time)
@output << sprintf("%#{TIME_WIDTH}.2f", method.wait_time)
@output << sprintf("%#{TIME_WIDTH}.2f", method.children_time)
@output << sprintf("%#{CALL_WIDTH}i", method.called)
@output << sprintf(" %s", method_name(method))
if print_file
@output << sprintf(" %s:%s", method.source_file, method.line)
end
@output << "\n"

print_children(children)
end
end
end

def print_parent(parent, method)
@output << " " * 2 * PERCENTAGE_WIDTH
@output << sprintf("%#{TIME_WIDTH}.2f", parent.total_time)
@output << sprintf("%#{TIME_WIDTH}.2f", parent.self_time)
@output << sprintf("%#{TIME_WIDTH}.2f", parent.wait_time)
@output << sprintf("%#{TIME_WIDTH}.2f", parent.children_time)

call_called = "#{parent.called}/#{method.called}"
@output << sprintf("%#{CALL_WIDTH}s", call_called)
@output << sprintf(" %s", parent.parent.target.full_name)
@output << "\n"
end

def print_children(children)
children.each do |child|
@output << " " * 2 * PERCENTAGE_WIDTH

@output << sprintf("%#{TIME_WIDTH}.2f", child.total_time)
@output << sprintf("%#{TIME_WIDTH}.2f", child.self_time)
@output << sprintf("%#{TIME_WIDTH}.2f", child.wait_time)
@output << sprintf("%#{TIME_WIDTH}.2f", 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

end #end class

end #end module

91 changes: 91 additions & 0 deletions lib/ruby-prof/graph_printer_without_aggregation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@

module RubyProf

class GraphPrinterWithoutAggregation < GraphPrinter
private
def print_methods(thread_id, methods)
# Sort methods from longest to shortest total time
methods = methods.sort

toplevel = methods.last
total_time = toplevel.total_time
total_time = 0.01 if total_time == 0

print_heading(thread_id)

# Print each method in total time order
methods.reverse_each do |method|
total_percentage = (method.total_time/total_time) * 100
self_percentage = (method.self_time/total_time) * 100

next if total_percentage < min_percent

parents = method.call_infos.map{|caller| caller if caller.parent}
children = method.children
call_tree = Hash.new
parents.each do |parent|
call_tree[parent] = Array.new
if parent
children.each do |child|
call_tree[parent] << child if child.call_sequence.include?(parent.call_sequence)
end
else
call_tree[parent] = children
end
end

call_tree.each do |parent, children|
@output << "-" * 80 << "\n"
print_parent(parent, method) if parent

# 1 is for % sign
@output << sprintf("%#{PERCENTAGE_WIDTH-1}.2f\%", total_percentage)
@output << sprintf("%#{PERCENTAGE_WIDTH-1}.2f\%", self_percentage)
@output << sprintf("%#{TIME_WIDTH}.2f", method.total_time)
@output << sprintf("%#{TIME_WIDTH}.2f", method.self_time)
@output << sprintf("%#{TIME_WIDTH}.2f", method.wait_time)
@output << sprintf("%#{TIME_WIDTH}.2f", method.children_time)
@output << sprintf("%#{CALL_WIDTH}i", method.called)
@output << sprintf(" %s", method_name(method))
if print_file
@output << sprintf(" %s:%s", method.source_file, method.line)
end
@output << "\n"

print_children(children)
end
end
end

def print_parent(parent, method)
@output << " " * 2 * PERCENTAGE_WIDTH
@output << sprintf("%#{TIME_WIDTH}.2f", parent.total_time)
@output << sprintf("%#{TIME_WIDTH}.2f", parent.self_time)
@output << sprintf("%#{TIME_WIDTH}.2f", parent.wait_time)
@output << sprintf("%#{TIME_WIDTH}.2f", parent.children_time)

call_called = "#{parent.called}/#{method.called}"
@output << sprintf("%#{CALL_WIDTH}s", call_called)
@output << sprintf(" %s", parent.parent.target.full_name)
@output << "\n"
end

def print_children(children)
children.each do |child|
@output << " " * 2 * PERCENTAGE_WIDTH

@output << sprintf("%#{TIME_WIDTH}.2f", child.total_time)
@output << sprintf("%#{TIME_WIDTH}.2f", child.self_time)
@output << sprintf("%#{TIME_WIDTH}.2f", child.wait_time)
@output << sprintf("%#{TIME_WIDTH}.2f", 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

end #end class
end