ruby-prof 0.11.0.rc1-x86-mingw32 → 0.11.0.rc2-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 +20 -5
- data/README.rdoc +10 -3
- data/ext/ruby_prof/rp_call_info.c +108 -79
- data/ext/ruby_prof/rp_call_info.h +1 -0
- data/ext/ruby_prof/rp_measure_cpu_time.c +111 -111
- data/ext/ruby_prof/rp_measure_gc_runs.c +1 -1
- data/ext/ruby_prof/rp_measure_memory.c +1 -1
- data/ext/ruby_prof/rp_measure_process_time.c +71 -71
- data/ext/ruby_prof/rp_measure_wall_time.c +1 -1
- data/ext/ruby_prof/rp_method.c +143 -73
- data/ext/ruby_prof/rp_method.h +7 -4
- data/ext/ruby_prof/rp_stack.c +16 -1
- data/ext/ruby_prof/rp_stack.h +4 -1
- data/ext/ruby_prof/rp_thread.c +165 -35
- data/ext/ruby_prof/rp_thread.h +8 -2
- data/ext/ruby_prof/ruby_prof.c +164 -171
- data/ext/ruby_prof/ruby_prof.h +53 -54
- data/ext/ruby_prof/vc/ruby_prof.sln +26 -0
- data/ext/ruby_prof/vc/ruby_prof.vcxproj +109 -0
- data/ext/ruby_prof/vc/ruby_prof_18.vcxproj +105 -0
- data/lib/1.8/ruby_prof.so +0 -0
- data/lib/1.9/ruby_prof.so +0 -0
- data/lib/ruby-prof/aggregate_call_info.rb +9 -7
- data/lib/ruby-prof/call_info.rb +2 -27
- data/lib/ruby-prof/call_info_visitor.rb +42 -0
- data/lib/ruby-prof/{empty.png → images/empty.png} +0 -0
- data/lib/ruby-prof/{minus.png → images/minus.png} +0 -0
- data/lib/ruby-prof/{plus.png → images/plus.png} +0 -0
- data/lib/ruby-prof/method_info.rb +13 -15
- data/lib/ruby-prof/{abstract_printer.rb → printers/abstract_printer.rb} +36 -2
- data/lib/ruby-prof/printers/call_info_printer.rb +40 -0
- data/lib/ruby-prof/{call_stack_printer.rb → printers/call_stack_printer.rb} +11 -16
- data/lib/ruby-prof/{call_tree_printer.rb → printers/call_tree_printer.rb} +4 -4
- data/lib/ruby-prof/{dot_printer.rb → printers/dot_printer.rb} +11 -31
- data/lib/ruby-prof/{flat_printer.rb → printers/flat_printer.rb} +26 -35
- data/lib/ruby-prof/{flat_printer_with_line_numbers.rb → printers/flat_printer_with_line_numbers.rb} +14 -25
- data/lib/ruby-prof/printers/graph_html_printer.rb +248 -0
- data/lib/ruby-prof/{graph_printer.rb → printers/graph_printer.rb} +31 -73
- data/lib/ruby-prof/{multi_printer.rb → printers/multi_printer.rb} +0 -0
- data/lib/ruby-prof/profile.rb +27 -22
- data/lib/ruby-prof/rack.rb +22 -12
- data/ruby-prof.gemspec +58 -0
- data/test/aggregate_test.rb +6 -6
- data/test/call_info_visitor_test.rb +31 -0
- data/test/duplicate_names_test.rb +1 -1
- data/test/dynamic_method_test.rb +1 -1
- data/test/enumerable_test.rb +1 -1
- data/test/exclude_threads_test.rb +2 -2
- data/test/gc_test.rb +35 -0
- data/test/line_number_test.rb +2 -2
- data/test/measure_cpu_time_test.rb +5 -5
- data/test/measure_process_time_test.rb +5 -5
- data/test/measure_wall_time_test.rb +5 -5
- data/test/method_elimination_test.rb +3 -3
- data/test/module_test.rb +1 -1
- data/test/no_method_class_test.rb +1 -1
- data/test/printers_test.rb +16 -8
- data/test/recursive_test.rb +115 -91
- data/test/stack_test.rb +1 -1
- data/test/start_stop_test.rb +13 -13
- data/test/summarize_test.rb +48 -0
- data/test/test_suite.rb +1 -0
- data/test/thread_test.rb +16 -12
- data/test/unique_call_path_test.rb +10 -10
- metadata +65 -85
- data/lib/1.9/ruby_prof.exp +0 -0
- data/lib/1.9/ruby_prof.ilk +0 -0
- data/lib/1.9/ruby_prof.lib +0 -0
- data/lib/1.9/ruby_prof.pdb +0 -0
- data/lib/ruby-prof.rb +0 -70
- data/lib/ruby-prof/graph_html_printer.rb +0 -286
- data/lib/ruby-prof/symbol_to_proc.rb +0 -10
- data/lib/ruby_prof.exp +0 -0
- data/lib/ruby_prof.ilk +0 -0
- data/lib/ruby_prof.lib +0 -0
- data/lib/ruby_prof.pdb +0 -0
- data/lib/ruby_prof.so +0 -0
- data/lib/unprof.rb +0 -10
- data/test/do_nothing.rb +0 -0
| @@ -0,0 +1,42 @@ | |
| 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_method.call_infos.each do |call_info|
         | 
| 30 | 
            +
                    self.visit_call_info(call_info)
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def visit_call_info(call_info)
         | 
| 35 | 
            +
                  self.block.call(call_info, :enter)
         | 
| 36 | 
            +
                  call_info.children.each do |child|
         | 
| 37 | 
            +
                    visit_call_info(child)
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
                  self.block.call(call_info, :exit)
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
            end
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| @@ -29,7 +29,7 @@ module RubyProf | |
| 29 29 | 
             
                def total_time
         | 
| 30 30 | 
             
                  @total_time ||= begin
         | 
| 31 31 | 
             
                    call_infos.inject(0) do |sum, call_info|
         | 
| 32 | 
            -
                      sum += call_info.total_time  | 
| 32 | 
            +
                      sum += call_info.total_time unless call_info.recursive
         | 
| 33 33 | 
             
                      sum
         | 
| 34 34 | 
             
                    end
         | 
| 35 35 | 
             
                  end
         | 
| @@ -38,7 +38,8 @@ module RubyProf | |
| 38 38 | 
             
                def self_time
         | 
| 39 39 | 
             
                  @self_time ||= begin
         | 
| 40 40 | 
             
                    call_infos.inject(0) do |sum, call_info|
         | 
| 41 | 
            -
                      sum += call_info.self_time
         | 
| 41 | 
            +
                      sum += call_info.self_time  unless call_info.recursive
         | 
| 42 | 
            +
                      sum
         | 
| 42 43 | 
             
                    end
         | 
| 43 44 | 
             
                  end
         | 
| 44 45 | 
             
                end
         | 
| @@ -46,7 +47,8 @@ module RubyProf | |
| 46 47 | 
             
                def wait_time
         | 
| 47 48 | 
             
                  @wait_time ||= begin
         | 
| 48 49 | 
             
                    call_infos.inject(0) do |sum, call_info|
         | 
| 49 | 
            -
                      sum += call_info.wait_time
         | 
| 50 | 
            +
                      sum += call_info.wait_time unless call_info.recursive
         | 
| 51 | 
            +
                      sum
         | 
| 50 52 | 
             
                    end
         | 
| 51 53 | 
             
                  end
         | 
| 52 54 | 
             
                end
         | 
| @@ -54,7 +56,7 @@ module RubyProf | |
| 54 56 | 
             
                def children_time
         | 
| 55 57 | 
             
                  @children_time ||= begin
         | 
| 56 58 | 
             
                    call_infos.inject(0) do |sum, call_info|
         | 
| 57 | 
            -
                      sum += call_info.children_time  | 
| 59 | 
            +
                      sum += call_info.children_time  unless call_info.recursive
         | 
| 58 60 | 
             
                      sum
         | 
| 59 61 | 
             
                    end
         | 
| 60 62 | 
             
                  end
         | 
| @@ -74,6 +76,12 @@ module RubyProf | |
| 74 76 | 
             
                  end
         | 
| 75 77 | 
             
                end
         | 
| 76 78 |  | 
| 79 | 
            +
                def recursive?
         | 
| 80 | 
            +
                  call_infos.detect do |call_info|
         | 
| 81 | 
            +
                    call_info.recursive
         | 
| 82 | 
            +
                  end
         | 
| 83 | 
            +
                end
         | 
| 84 | 
            +
             | 
| 77 85 | 
             
                def children
         | 
| 78 86 | 
             
                  @children ||= begin
         | 
| 79 87 | 
             
                    call_infos.map do |call_info|
         | 
| @@ -109,17 +117,7 @@ module RubyProf | |
| 109 117 | 
             
                end
         | 
| 110 118 |  | 
| 111 119 | 
             
                def to_s
         | 
| 112 | 
            -
                  full_name
         | 
| 113 | 
            -
                end
         | 
| 114 | 
            -
             | 
| 115 | 
            -
                def dump
         | 
| 116 | 
            -
                  res = ""
         | 
| 117 | 
            -
                  res << "MINFO: #{klass_name}##{method_name} total_time: #{total_time} (#{full_name})\n"
         | 
| 118 | 
            -
                  call_infos.each do |ci|
         | 
| 119 | 
            -
                    pinfo = ci.root? ? "TOPLEVEL" : (p=ci.parent.target; "#{p.klass_name}##{p.method_name} (#{ci.parent.object_id}) (#{p.full_name})")
         | 
| 120 | 
            -
                    res << "CINFO[#{ci.object_id}] called #{ci.called} times from #{pinfo}\n"
         | 
| 121 | 
            -
                  end
         | 
| 122 | 
            -
                  res
         | 
| 120 | 
            +
                  "#{self.full_name} (c: #{self.called}, tt: #{self.total_time}, st: #{self.self_time}, ct: #{self.children_time})"
         | 
| 123 121 | 
             
                end
         | 
| 124 122 |  | 
| 125 123 | 
             
                # remove method from the call graph. should not be called directly.
         | 
| @@ -2,10 +2,12 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            module RubyProf
         | 
| 4 4 | 
             
              class AbstractPrinter
         | 
| 5 | 
            +
                # Create a new printer.
         | 
| 6 | 
            +
                #
         | 
| 7 | 
            +
                # result should be the output generated from a profiling run
         | 
| 5 8 | 
             
                def initialize(result)
         | 
| 6 9 | 
             
                  @result = result
         | 
| 7 10 | 
             
                  @output = nil
         | 
| 8 | 
            -
                  @options = {}
         | 
| 9 11 | 
             
                end
         | 
| 10 12 |  | 
| 11 13 | 
             
                # Specify print options.
         | 
| @@ -47,5 +49,37 @@ module RubyProf | |
| 47 49 | 
             
                  end
         | 
| 48 50 | 
             
                  name
         | 
| 49 51 | 
             
                end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                # Print a profiling report to the provided output.
         | 
| 54 | 
            +
                #
         | 
| 55 | 
            +
                # output - Any IO object, including STDOUT or a file.
         | 
| 56 | 
            +
                # The default value is STDOUT.
         | 
| 57 | 
            +
                #
         | 
| 58 | 
            +
                # options - Hash of print options.  See #setup_options
         | 
| 59 | 
            +
                # for more information.  Note that each printer can
         | 
| 60 | 
            +
                # define its own set of options.
         | 
| 61 | 
            +
                def print(output = STDOUT, options = {})
         | 
| 62 | 
            +
                  @output = output
         | 
| 63 | 
            +
                  setup_options(options)
         | 
| 64 | 
            +
                  print_threads
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                def print_threads
         | 
| 68 | 
            +
                  @result.threads.each do |thread|
         | 
| 69 | 
            +
                    print_thread(thread)
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                def print_thread(thread)
         | 
| 74 | 
            +
                  print_header(thread)
         | 
| 75 | 
            +
                  print_methods(thread)
         | 
| 76 | 
            +
                  print_footer(thread)
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                def print_header(thread)
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                def print_footer(thread)
         | 
| 83 | 
            +
                end
         | 
| 50 84 | 
             
              end
         | 
| 51 | 
            -
            end
         | 
| 85 | 
            +
            end
         | 
| @@ -0,0 +1,40 @@ | |
| 1 | 
            +
            # encoding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module RubyProf
         | 
| 4 | 
            +
              # Prints out the call graph based on CallInfo instances.  This
         | 
| 5 | 
            +
              # is mainly for debugging purposes as it provides access into
         | 
| 6 | 
            +
              # into RubyProf's internals.
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              class CallInfoPrinter < AbstractPrinter
         | 
| 9 | 
            +
                TIME_WIDTH = 0
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                private
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def print_header(thread)
         | 
| 14 | 
            +
                  @output << "Thread ID: #{thread.id}\n"
         | 
| 15 | 
            +
                  @output << "Total Time: #{thread.top_method.total_time}\n"
         | 
| 16 | 
            +
                  @output << "Sort by: #{sort_method}\n"
         | 
| 17 | 
            +
                  @output << "\n"
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def print_methods(thread)
         | 
| 21 | 
            +
                  visitor = CallInfoVisitor.new(thread)
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  visitor.visit do |call_info, event|
         | 
| 24 | 
            +
                    if event == :enter
         | 
| 25 | 
            +
                      @output << "  " * call_info.depth
         | 
| 26 | 
            +
                      @output << call_info.target.full_name
         | 
| 27 | 
            +
                      @output << " ("
         | 
| 28 | 
            +
                      @output << "tt:#{sprintf("%#{TIME_WIDTH}.2f", call_info.total_time)}, "
         | 
| 29 | 
            +
                      @output << "st:#{sprintf("%#{TIME_WIDTH}.2f", call_info.self_time)}, "
         | 
| 30 | 
            +
                      @output << "wt:#{sprintf("%#{TIME_WIDTH}.2f", call_info.wait_time)}, "
         | 
| 31 | 
            +
                      @output << "ct:#{sprintf("%#{TIME_WIDTH}.2f", call_info.children_time)}, "
         | 
| 32 | 
            +
                      @output << "call:#{call_info.called}, "
         | 
| 33 | 
            +
                      @output << "rec:#{call_info.recursive}"
         | 
| 34 | 
            +
                      @output << ")"
         | 
| 35 | 
            +
                      @output << "\n"
         | 
| 36 | 
            +
                    end
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
            end
         | 
| @@ -42,28 +42,23 @@ module RubyProf | |
| 42 42 | 
             
                    @graph_html = "file://" + @graph_html if @graph_html[0]=="/"
         | 
| 43 43 | 
             
                  end
         | 
| 44 44 |  | 
| 45 | 
            -
                  @overall_threads_time = 0.0
         | 
| 46 | 
            -
                  @threads_totals = Hash.new
         | 
| 47 | 
            -
                  @result.threads.each do |thread_id, methods|
         | 
| 48 | 
            -
                    roots = methods.select{|m| m.root?}
         | 
| 49 | 
            -
                    thread_total_time = sum(roots.map{|r| self.total_time(r.call_infos)})
         | 
| 50 | 
            -
                    @overall_threads_time += thread_total_time
         | 
| 51 | 
            -
                    @threads_totals[thread_id] = thread_total_time
         | 
| 52 | 
            -
                  end
         | 
| 53 | 
            -
             | 
| 54 45 | 
             
                  print_header
         | 
| 55 46 |  | 
| 56 | 
            -
                  @result.threads. | 
| 57 | 
            -
                     | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 47 | 
            +
                  @overall_threads_time = @result.threads.inject(0) do |val, thread|
         | 
| 48 | 
            +
                    val += thread.top_method.total_time
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  @result.threads.each do |thread|
         | 
| 52 | 
            +
                    @current_thread_id = thread.id
         | 
| 53 | 
            +
                    @overall_time = thread.top_method.total_time
         | 
| 54 | 
            +
                    @output.print "<div class=\"thread\">Thread: #{thread.id} (#{"%4.2f%%" % ((@overall_time/@overall_threads_time)*100)} ~ #{@overall_time})</div>"
         | 
| 60 55 | 
             
                    @output.print "<ul name=\"thread\">"
         | 
| 61 | 
            -
                     | 
| 56 | 
            +
                    thread.methods.each do |m|
         | 
| 62 57 | 
             
                      # $stderr.print m.dump
         | 
| 63 58 | 
             
                      next unless m.root?
         | 
| 64 59 | 
             
                      m.call_infos.each do |ci|
         | 
| 65 60 | 
             
                        next unless ci.root?
         | 
| 66 | 
            -
                        print_stack ci,  | 
| 61 | 
            +
                        print_stack ci, thread.top_method.total_time
         | 
| 67 62 | 
             
                      end
         | 
| 68 63 | 
             
                    end
         | 
| 69 64 | 
             
                    @output.print "</ul>"
         | 
| @@ -185,7 +180,7 @@ module RubyProf | |
| 185 180 | 
             
                def copy_image_files
         | 
| 186 181 | 
             
                  if @output.is_a?(File)
         | 
| 187 182 | 
             
                    target_dir = File.dirname(@output.path)
         | 
| 188 | 
            -
                    image_dir = File.dirname(__FILE__)
         | 
| 183 | 
            +
                    image_dir = File.join(File.dirname(__FILE__), '..', 'images')
         | 
| 189 184 | 
             
                    %w(empty plus minus).each do |img|
         | 
| 190 185 | 
             
                      source_file = "#{image_dir}/#{img}.png"
         | 
| 191 186 | 
             
                      target_file = "#{target_dir}/#{img}.png"
         | 
| @@ -54,8 +54,8 @@ module RubyProf | |
| 54 54 | 
             
                end
         | 
| 55 55 |  | 
| 56 56 | 
             
                def print_threads
         | 
| 57 | 
            -
                  @result.threads.each do | | 
| 58 | 
            -
                     | 
| 57 | 
            +
                  @result.threads.each do |thread|
         | 
| 58 | 
            +
                    print_thread(thread)
         | 
| 59 59 | 
             
                  end
         | 
| 60 60 | 
             
                end
         | 
| 61 61 |  | 
| @@ -67,8 +67,8 @@ module RubyProf | |
| 67 67 | 
             
                  File.expand_path(method.source_file)
         | 
| 68 68 | 
             
                end
         | 
| 69 69 |  | 
| 70 | 
            -
                def  | 
| 71 | 
            -
                  methods.reverse_each do |method|
         | 
| 70 | 
            +
                def print_thread(thread)
         | 
| 71 | 
            +
                  thread.methods.reverse_each do |method|
         | 
| 72 72 | 
             
                    # Print out the file and method name
         | 
| 73 73 | 
             
                    @output << "fl=#{file(method)}\n"
         | 
| 74 74 | 
             
                    @output << "fn=#{method_name(method)}\n"
         | 
| @@ -45,10 +45,8 @@ module RubyProf | |
| 45 45 | 
             
                  @output = output
         | 
| 46 46 | 
             
                  setup_options(options)
         | 
| 47 47 |  | 
| 48 | 
            -
                  total_time = thread_times.values.inject{|a,b| a+b}
         | 
| 49 | 
            -
                  
         | 
| 50 48 | 
             
                  puts 'digraph "Profile" {'
         | 
| 51 | 
            -
                  puts "label=\"#{mode_name} >=#{min_percent}%\\nTotal: #{total_time}\";"
         | 
| 49 | 
            +
                  #puts "label=\"#{mode_name} >=#{min_percent}%\\nTotal: #{total_time}\";"
         | 
| 52 50 | 
             
                  puts "labelloc=t;"
         | 
| 53 51 | 
             
                  puts "labeljust=l;"
         | 
| 54 52 | 
             
                  print_threads
         | 
| @@ -64,32 +62,14 @@ module RubyProf | |
| 64 62 | 
             
                  RubyProf.constants.find{|c| RubyProf.const_get(c) == RubyProf.measure_mode}
         | 
| 65 63 | 
             
                end
         | 
| 66 64 |  | 
| 67 | 
            -
                # Computes the total time per thread:
         | 
| 68 | 
            -
                def thread_times
         | 
| 69 | 
            -
                  @thread_times ||= begin
         | 
| 70 | 
            -
                    times = {}
         | 
| 71 | 
            -
                    @result.threads.each do |thread_id, methods|
         | 
| 72 | 
            -
                      toplevel = methods.sort.last
         | 
| 73 | 
            -
             | 
| 74 | 
            -
                      total_time = toplevel.total_time
         | 
| 75 | 
            -
                      # This looks like a hack for very small times... from GraphPrinter
         | 
| 76 | 
            -
                      total_time = 0.01 if total_time == 0 
         | 
| 77 | 
            -
                      times[thread_id] = total_time
         | 
| 78 | 
            -
                    end
         | 
| 79 | 
            -
                    
         | 
| 80 | 
            -
                    times
         | 
| 81 | 
            -
                  end
         | 
| 82 | 
            -
                end
         | 
| 83 | 
            -
                
         | 
| 84 65 | 
             
                def print_threads
         | 
| 85 | 
            -
                   | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 88 | 
            -
                    
         | 
| 89 | 
            -
                    print_methods(thread_id, methods)
         | 
| 66 | 
            +
                  @result.threads.each do |thread|
         | 
| 67 | 
            +
                    puts "subgraph \"Thread #{thread.id}\" {"
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                    print_thread(thread)
         | 
| 90 70 | 
             
                    puts "}"
         | 
| 91 71 |  | 
| 92 | 
            -
                    print_classes( | 
| 72 | 
            +
                    print_classes(thread)
         | 
| 93 73 | 
             
                  end
         | 
| 94 74 | 
             
                end
         | 
| 95 75 |  | 
| @@ -98,9 +78,9 @@ module RubyProf | |
| 98 78 | 
             
                  subject.object_id
         | 
| 99 79 | 
             
                end
         | 
| 100 80 |  | 
| 101 | 
            -
                def  | 
| 102 | 
            -
                  total_time =  | 
| 103 | 
            -
                  methods.sort_by(&sort_method).reverse_each do |method|
         | 
| 81 | 
            +
                def print_thread(thread)
         | 
| 82 | 
            +
                  total_time = thread.top_method.total_time
         | 
| 83 | 
            +
                  thread.methods.sort_by(&sort_method).reverse_each do |method|
         | 
| 104 84 | 
             
                    total_percentage = (method.total_time/total_time) * 100
         | 
| 105 85 |  | 
| 106 86 | 
             
                    next if total_percentage < min_percent
         | 
| @@ -111,9 +91,9 @@ module RubyProf | |
| 111 91 | 
             
                  end
         | 
| 112 92 | 
             
                end
         | 
| 113 93 |  | 
| 114 | 
            -
                def print_classes( | 
| 94 | 
            +
                def print_classes(thread)
         | 
| 115 95 | 
             
                  grouped = {}
         | 
| 116 | 
            -
                  methods.each{|m| grouped[m.klass_name] ||= []; grouped[m.klass_name] << m}
         | 
| 96 | 
            +
                  thread.methods.each{|m| grouped[m.klass_name] ||= []; grouped[m.klass_name] << m}
         | 
| 117 97 | 
             
                  grouped.each do |cls, methods2|
         | 
| 118 98 | 
             
                    # Filter down to just seen methods
         | 
| 119 99 | 
             
                    big_methods, small_methods  = methods2.partition{|m| @seen_methods.include? m}
         | 
| @@ -12,46 +12,31 @@ module RubyProf | |
| 12 12 | 
             
              #   printer.print(STDOUT, {})
         | 
| 13 13 | 
             
              #
         | 
| 14 14 | 
             
              class FlatPrinter < AbstractPrinter
         | 
| 15 | 
            -
                #  | 
| 16 | 
            -
                 | 
| 17 | 
            -
             | 
| 18 | 
            -
                # The default value is STDOUT.
         | 
| 19 | 
            -
                #
         | 
| 20 | 
            -
                # options - Hash of print options.  See #setup_options
         | 
| 21 | 
            -
                # for more information.
         | 
| 22 | 
            -
                #
         | 
| 23 | 
            -
                def print(output = STDOUT, options = {})
         | 
| 24 | 
            -
                  @output = output
         | 
| 25 | 
            -
                  # Now sort methods by largest self time by default,
         | 
| 26 | 
            -
                  # not total time like in other printouts
         | 
| 27 | 
            -
                  options[:sort_method] ||= :self_time
         | 
| 28 | 
            -
                  setup_options(options)
         | 
| 29 | 
            -
                  print_threads
         | 
| 15 | 
            +
                # Override for this printer to sort by self time by default
         | 
| 16 | 
            +
                def sort_method
         | 
| 17 | 
            +
                  @options[:sort_method] || :self_time
         | 
| 30 18 | 
             
                end
         | 
| 31 19 |  | 
| 32 20 | 
             
                private
         | 
| 33 21 |  | 
| 34 | 
            -
                def print_threads
         | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
                end
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                def print_methods(thread_id, methods)
         | 
| 42 | 
            -
                  # Get total time
         | 
| 43 | 
            -
                  toplevel = methods.max
         | 
| 44 | 
            -
                  total_time = toplevel.total_time
         | 
| 45 | 
            -
                  if total_time == 0
         | 
| 46 | 
            -
                    total_time = 0.01
         | 
| 47 | 
            -
                  end
         | 
| 48 | 
            -
             | 
| 49 | 
            -
                  methods = methods.sort_by(&sort_method).reverse
         | 
| 22 | 
            +
                #def print_threads
         | 
| 23 | 
            +
                #  @result.threads.each do |thread|
         | 
| 24 | 
            +
                #    print_thread(thread)
         | 
| 25 | 
            +
                #    @output << "\n" * 2
         | 
| 26 | 
            +
                #  end
         | 
| 27 | 
            +
                #end
         | 
| 50 28 |  | 
| 51 | 
            -
             | 
| 52 | 
            -
                  @output << " | 
| 29 | 
            +
                def print_header(thread)
         | 
| 30 | 
            +
                  @output << "Thread ID: %d\n" % thread.id
         | 
| 31 | 
            +
                  @output << "Total: %0.6f\n" % thread.top_method.total_time
         | 
| 32 | 
            +
                  @output << "Sort by: #{sort_method}\n"
         | 
| 53 33 | 
             
                  @output << "\n"
         | 
| 54 | 
            -
                  @output << " %self     total     self     wait    child    calls | 
| 34 | 
            +
                  @output << " %self     total     self     wait    child    calls   name\n"
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def print_methods(thread)
         | 
| 38 | 
            +
                  total_time = thread.top_method.total_time
         | 
| 39 | 
            +
                  methods = thread.methods.sort_by(&sort_method).reverse
         | 
| 55 40 |  | 
| 56 41 | 
             
                  sum = 0
         | 
| 57 42 | 
             
                  methods.each do |method|
         | 
| @@ -62,16 +47,22 @@ module RubyProf | |
| 62 47 | 
             
                    #self_time_called = method.called > 0 ? method.self_time/method.called : 0
         | 
| 63 48 | 
             
                    #total_time_called = method.called > 0? method.total_time/method.called : 0
         | 
| 64 49 |  | 
| 65 | 
            -
                    @output << "%6.2f  %8.2f %8.2f %8.2f %8.2f %8d  %s\n" % [
         | 
| 50 | 
            +
                    @output << "%6.2f  %8.2f %8.2f %8.2f %8.2f %8d  %s%s \n" % [
         | 
| 66 51 | 
             
                                  method.self_time / total_time * 100, # %self
         | 
| 67 52 | 
             
                                  method.total_time,                   # total
         | 
| 68 53 | 
             
                                  method.self_time,                    # self
         | 
| 69 54 | 
             
                                  method.wait_time,                    # wait
         | 
| 70 55 | 
             
                                  method.children_time,                # children
         | 
| 71 56 | 
             
                                  method.called,                       # calls
         | 
| 57 | 
            +
                                  method.recursive? ? "*" : " ",       # cycle
         | 
| 72 58 | 
             
                                  method_name(method)                  # name
         | 
| 73 59 | 
             
                              ]
         | 
| 74 60 | 
             
                  end
         | 
| 75 61 | 
             
                end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                def print_footer(thread)
         | 
| 64 | 
            +
                  @output << "\n"
         | 
| 65 | 
            +
                  @output << "* in front of method name means it is recursively called\n"
         | 
| 66 | 
            +
                end
         | 
| 76 67 | 
             
              end
         | 
| 77 68 | 
             
            end
         |