This page contains automated test results for code from O'Reilly's Ruby Cookbook. If this code looks interesting or useful, you might want to buy the whole book.
Who's Calling That Method? A Call Graph Analyzer | ||
---|---|---|
Code | Expected | Actual |
% cumulative self self total time seconds seconds calls ms/call ms/call name 12.19 2.74 2.74 4930 0.56 0.77 Array#each class CallTracker # Initialize and start the trace. def initialize(show_stack_depth=1) @show_stack_depth = show_stack_depth @to_trace = Hash.new { |h,k| h[k] = {} } start at_exit { stop } end # Register a class/method combination as being interesting. Subsequent calls # to the method will be tallied by tally_calls. def register(klass, method_symbol) @to_trace[klass][method_symbol] = {} end # Tells the Ruby interpreter to call tally_calls whenever it's about to # do anything interesting. def start set_trace_func method(:tally_calls).to_proc end # Stops the profiler, and prints a report of the interesting calls made # while it was running. def stop(out=$stderr) set_trace_func nil report(out) end # If the interpreter is about to call a method we find interesting, # increment the count for that method. def tally_calls(event, file, line, symbol, binding, klass) if @to_trace[klass] and @to_trace[klass][symbol] and (event == 'call' or event =='c-call') stack = caller stack = stack[1..(@show_stack_depth ? @show_stack_depth : stack.size)] @to_trace[klass][symbol][stack] ||= 0 @to_trace[klass][symbol][stack] += 1 end end # Prints a report of the lines of code that called interesting # methods, sorted so that the the most active lines of code show up # first. def report(out=$stderr) first = true @to_trace.each do |klass, symbols| symbols.each do |symbol, calls| total = calls.inject(0) { |sum, ct| sum + ct[1] } padding = total.to_s.size separator = (klass.is_a? Class) ? '#' : '.' plural = (total == 1) ? '' : 's' stack_join = "\n" + (' ' * (padding+2)) first ? first = false : out.puts out.puts "#{total} call#{plural} to #{klass}#{separator}#{symbol}" (calls.sort_by { |caller, times| -times }).each do |caller, times| out.puts " %#{padding}.d #{caller.join(stack_join)}" % times end end end end end require 'rubygems' require 'rubyful_soup' tracker = CallTracker.new tracker.register(Array, :each) BeautifulSoup.new(open('test.html') { |f| f.read }) tracker.stop($stdout) |
4930 calls to Array#each 1671 ./rubyful_soup.rb:715:in `pop_to_tag' 1631 ./rubyful_soup.rb:567:in `unknown_starttag' 1627 ./rubyful_soup.rb:751:in `smart_pop' 1 ./rubyful_soup.rb:510:in `feed' |
SyntaxError: compile error (irb):1: parse error, unexpected tIDENTIFIER, expecting $ % cumulative self self total ^ from (irb):1 SyntaxError: compile error (irb):2: parse error, unexpected tIDENTIFIER, expecting kDO or '{' or '(' time seconds seconds calls ms/call ms/call name ^ (irb):2: parse error, unexpected tIDENTIFIER, expecting kDO or '{' or '(' time seconds seconds calls ms/call ms/call name ^ from (irb):2 SyntaxError: compile error (irb):3: parse error, unexpected tFLOAT, expecting $ 12.19 2.74 2.74 4930 0.56 0.77 Array#each ^ from (irb):3 9 calls to Array#each 4 /usr/lib/ruby/gems/1.8/gems/rubyful_soup-1.0.4/lib/rubyful_soup.rb:232:in `attrs' 4 /usr/lib/ruby/gems/1.8/gems/rubyful_soup-1.0.4/lib/rubyful_soup.rb:341:in `render_contents' 1 /usr/lib/ruby/gems/1.8/gems/rubyful_soup-1.0.4/lib/rubyful_soup.rb:536:in `feed' |