class RubyProf::DotPrinter
Generates a graphviz graph in dot format. To use the dot printer:
result = RubyProf.profile do [code to profile] end printer = RubyProf::DotPrinter.new(result) printer.print(STDOUT)
You can use either dot viewer such as GraphViz, or the dot command line tool to reformat the output into a wide variety of outputs:
dot -Tpng graph.dot > graph.png
Constants
- CLASS_COLOR
- EDGE_COLOR
Public Class Methods
Creates the DotPrinter
using a RubyProf::Proile.
RubyProf::AbstractPrinter::new
# File lib/ruby-prof/printers/dot_printer.rb, line 26 def initialize(result) super(result) @seen_methods = Set.new end
Public Instance Methods
Print a graph report to the provided output.
output - Any IO object, including STDOUT or a file. The default value is STDOUT.
options - Hash of print options. See setup_options
for more information.
When profiling results that cover a large number of method calls it helps to use the :min_percent option, for example:
DotPrinter.new(result).print(STDOUT, :min_percent=>5)
# File lib/ruby-prof/printers/dot_printer.rb, line 44 def print(output = STDOUT, options = {}) @output = output setup_options(options) puts 'digraph "Profile" {' #puts "label=\"#{mode_name} >=#{min_percent}%\\nTotal: #{total_time}\";" puts "labelloc=t;" puts "labeljust=l;" print_threads puts '}' end
Private Instance Methods
Determines an ID to use to represent the subject in the Dot file.
# File lib/ruby-prof/printers/dot_printer.rb, line 77 def dot_id(subject) subject.object_id end
Something of a hack, figure out which constant went with the RubyProf.measure_mode
so that we can display it. Otherwise it's easy to forget what measurement was made.
# File lib/ruby-prof/printers/dot_printer.rb, line 61 def mode_name RubyProf.constants.find{|c| RubyProf.const_get(c) == RubyProf.measure_mode} end
# File lib/ruby-prof/printers/dot_printer.rb, line 94 def print_classes(thread) grouped = {} thread.methods.each{|m| grouped[m.klass_name] ||= []; grouped[m.klass_name] << m} grouped.each do |cls, methods2| # Filter down to just seen methods big_methods = methods2.select{|m| @seen_methods.include? m} if !big_methods.empty? puts "subgraph cluster_#{cls.object_id} {" puts "label = \"#{cls}\";" puts "fontcolor = #{CLASS_COLOR};" puts "fontsize = 16;" puts "color = #{CLASS_COLOR};" big_methods.each do |m| puts "#{m.object_id};" end puts "}" end end end
# File lib/ruby-prof/printers/dot_printer.rb, line 115 def print_edges(total_time, method) method.aggregate_children.sort_by(&:total_time).reverse.each do |child| target_percentage = (child.target.total_time / total_time) * 100.0 next if target_percentage < min_percent # Get children method puts "#{dot_id(method)} -> #{dot_id(child.target)} [label=\"#{child.called}/#{child.target.called}\" fontsize=10 fontcolor=#{EDGE_COLOR}];" end end
# File lib/ruby-prof/printers/dot_printer.rb, line 81 def print_thread(thread) total_time = thread.total_time thread.methods.sort_by(&sort_method).reverse_each do |method| total_percentage = (method.total_time/total_time) * 100 next if total_percentage < min_percent name = method_name(method).split("#").last puts "#{dot_id(method)} [label=\"#{name}\\n(#{total_percentage.round}%)\"];" @seen_methods << method print_edges(total_time, method) end end
# File lib/ruby-prof/printers/dot_printer.rb, line 65 def print_threads @result.threads.each do |thread| puts "subgraph \"Thread #{thread.id}\" {" print_thread(thread) puts "}" print_classes(thread) end end
Silly little helper for printing to the @output
# File lib/ruby-prof/printers/dot_printer.rb, line 127 def puts(str) @output.puts(str) end