Class | RubyProf::GraphHtmlPrinter |
In: |
lib/ruby-prof/graph_html_printer.rb
|
Parent: | Object |
Generates graph profile reports as html. To use the grap html printer:
result = RubyProf.profile do [code to profile] end printer = RubyProf::GraphHtmlPrinter.new(result, 5) printer.print(STDOUT, 0)
The constructor takes two arguments. The first is a RubyProf::Result object generated from a profiling run. The second is the minimum %total (the methods total time divided by the overall total time) that a method must take for it to be printed out in the report. Use this parameter to eliminate methods that are not important to the overall profiling results.
PERCENTAGE_WIDTH | = | 8 |
TIME_WIDTH | = | 10 |
CALL_WIDTH | = | 20 |
Create a GraphPrinter. Result is a RubyProf::Result object generated from a profiling run.
# File lib/ruby-prof/graph_html_printer.rb, line 29 29: def initialize(result) 30: @result = result 31: end
Creates a link to a method. Note that we do not create links to methods which are under the min_perecent specified by the user, since they will not be printed out.
# File lib/ruby-prof/graph_html_printer.rb, line 75 75: def create_link(thread_id, name) 76: # Get method 77: method = @result.threads[thread_id][name] 78: 79: if self.total_percent(method) < @min_percent 80: # Just return name 81: name 82: else 83: # Create link 84: "<a href=\"##{link_name(thread_id, name)}\">#{name}</a>" 85: end 86: end
# File lib/ruby-prof/graph_html_printer.rb, line 88 88: def link_name(thread_id, name)\ 89: name.gsub(/[><#\.\?=:]/,"_") + "_" + thread_id.to_s 90: end
Print a graph html report to the provided output.
output - Any IO oject, including STDOUT or a file. The default value is STDOUT.
min_percent - The minimum %total (the methods total time divided by the overall total time) that a method must take for it to be printed out in the report. Default value is 0.
# File lib/ruby-prof/graph_html_printer.rb, line 42 42: def print(output = STDOUT, min_percent = 0) 43: @output = output 44: @min_percent = min_percent 45: 46: _erbout = @output 47: erb = ERB.new(template, nil, nil) 48: @output << erb.result(binding) 49: end
# File lib/ruby-prof/graph_html_printer.rb, line 66 66: def self_percent(method) 67: overall_time = self.total_time(method.thread_id) 68: (method.self_time/overall_time) * 100 69: end
# File lib/ruby-prof/graph_html_printer.rb, line 92 92: def template 93: ' 94: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 95: <html> 96: <head> 97: <style media="all" type="text/css"> 98: table { 99: border-collapse: collapse; 100: border: 1px solid #CCC; 101: font-family: Verdana, Arial, Helvetica, sans-serif; 102: font-size: 9pt; 103: line-height: normal; 104: } 105: 106: th { 107: text-align: center; 108: border-top: 1px solid #FB7A31; 109: border-bottom: 1px solid #FB7A31; 110: background: #FFC; 111: padding: 0.3em; 112: border-left: 1px solid silver; 113: } 114: 115: tr.break td { 116: border: 0; 117: border-top: 1px solid #FB7A31; 118: padding: 0; 119: margin: 0; 120: } 121: 122: tr.method td { 123: font-weight: bold; 124: } 125: 126: td { 127: padding: 0.3em; 128: } 129: 130: td:first-child { 131: width: 190px; 132: } 133: 134: td { 135: border-left: 1px solid #CCC; 136: text-align: center; 137: } 138: </style> 139: </head> 140: <body> 141: <h1>Profile Report</h1> 142: <!-- Threads Table --> 143: <table> 144: <tr> 145: <th>Thread ID</th> 146: <th>Total Time</th> 147: </tr> 148: <% for thread_id, methods in @result.threads %> 149: <tr> 150: <td><a href="#<%= thread_id %>"><%= thread_id %></a></td> 151: <td><%= @result.toplevel(thread_id).total_time %></td> 152: </tr> 153: <% end %> 154: </table> 155: 156: <!-- Methods Tables --> 157: <% for thread_id, methods in @result.threads %> 158: <h2><a name="<%= thread_id %>">Thread <%= thread_id %></a></h2> 159: 160: <table> 161: <tr> 162: <th><%= sprintf("%#{PERCENTAGE_WIDTH}s", "%Total") %></th> 163: <th><%= sprintf("%#{PERCENTAGE_WIDTH}s", "%Self") %></th> 164: <th><%= sprintf("%#{TIME_WIDTH}s", "Total") %></th> 165: <th><%= sprintf("%#{TIME_WIDTH}s", "Self") %></th> 166: <th><%= sprintf("%#{TIME_WIDTH+2}s", "Children") %></th> 167: <th><%= sprintf("%#{CALL_WIDTH}s", "Calls") %></th> 168: <th>Name</th> 169: </tr> 170: 171: <% methods = methods.values.sort.reverse %> 172: <% for method in methods %> 173: <% method_total_percent = self.total_percent(method) %> 174: <% next if method_total_percent < @min_percent %> 175: <% method_self_percent = self.self_percent(method) %> 176: 177: <!-- Parents --> 178: <% for name, call_info in method.parents %> 179: <tr> 180: <td> </td> 181: <td> </td> 182: <td><%= sprintf("%#{TIME_WIDTH}.2f", call_info.total_time) %></td> 183: <td><%= sprintf("%#{TIME_WIDTH}.2f", call_info.self_time) %></td> 184: <td><%= sprintf("%#{TIME_WIDTH}.2f", call_info.children_time) %></td> 185: <% called = "#{call_info.called}/#{method.called}" %> 186: <td><%= sprintf("%#{CALL_WIDTH}s", called) %></td> 187: <td><%= create_link(thread_id, name) %></td> 188: </tr> 189: <% end %> 190: 191: <tr class="method"> 192: <td><%= sprintf("%#{PERCENTAGE_WIDTH-1}.2f\%", method_total_percent) %></td> 193: <td><%= sprintf("%#{PERCENTAGE_WIDTH-1}.2f\%", method_self_percent) %></td> 194: <td><%= sprintf("%#{TIME_WIDTH}.2f", method.total_time) %></td> 195: <td><%= sprintf("%#{TIME_WIDTH}.2f", method.self_time) %></td> 196: <td><%= sprintf("%#{TIME_WIDTH}.2f", method.children_time) %></td> 197: <td><%= sprintf("%#{CALL_WIDTH}i", method.called) %></td> 198: <td><a name="<%= link_name(thread_id, method.name) %>"><%= method.name %></a></td> 199: </tr> 200: 201: <!-- Children --> 202: <% for name, call_info in method.children %> 203: <% methods = @result.threads[thread_id] %> 204: <% child = methods[name] %> 205: 206: <tr> 207: <td> </td> 208: <td> </td> 209: <td><%= sprintf("%#{TIME_WIDTH}.2f", call_info.total_time) %></td> 210: <td><%= sprintf("%#{TIME_WIDTH}.2f", call_info.self_time) %></td> 211: <td><%= sprintf("%#{TIME_WIDTH}.2f", call_info.children_time) %></td> 212: <% called = "#{call_info.called}/#{child.called}" %> 213: <td><%= sprintf("%#{CALL_WIDTH}s", called) %></td> 214: <td><%= create_link(thread_id, name) %></td> 215: </tr> 216: <% end %> 217: <!-- Create divider row --> 218: <tr class="break"><td colspan="7"></td></tr> 219: <% end %> 220: </table> 221: <% end %> 222: </body> 223: </html>' 224: end
# File lib/ruby-prof/graph_html_printer.rb, line 61 61: def total_percent(method) 62: overall_time = self.total_time(method.thread_id) 63: (method.total_time/overall_time) * 100 64: end
These methods should be private but then ERB doesn’t work. Turn off RDOC though
# File lib/ruby-prof/graph_html_printer.rb, line 54 54: def total_time(thread_id) 55: toplevel = @result.toplevel(thread_id) 56: total_time = toplevel.total_time 57: total_time = 0.01 if total_time == 0 58: return total_time 59: end