From: Mathieu Bouchard Date: 2001-07-09T12:35:34+09:00 Subject: [ruby-talk:17523] Statistical Time-Consumption Profiler One gave an idea, But none had written the code. Here, Hear, Here it is. SProfile.rb ----------------8<--------------d�coupez-ici--------------8<---------------- # Statistical Time-Consumption Profiler # An alternative to Ruby's profile.rb # does not use set_trace_func(). # approximates the real thing by taking stack snapshots. # possibly more accurate # (profile.rb widens the C/Ruby speed gap while measuring) class CallStats CallStatsEntry = Struct.new(:method,:time,:time_nest) def initialize @table = {} end def eat_stack(stack) stack.each_with_index {|frame,i| next if i==0 method = File.basename(frame[0..frame.index(?:)]) pos = frame.rindex(?`) method << frame[pos+1..-2] if pos e = (@table[method] ||= CallStatsEntry.new(method,0,0)) e.time += 1 if i==1 e.time_nest += 1 } end def print_top_methods_to(stream) column = :time_nest #column = :time ks = @table.keys.sort {|a,b| @table[b].send(column) <=> @table[a].send(column) } i=0 ks.each {|k| v = @table[k] stream.printf "%40s %7d %7d\n", v.method, v.time, v.time_nest i+=1 break if i>=32 } end end foo = CallStats.new foo.eat_stack proc{caller}.call parent = $$ m=0 trap(12) { if m<1; m+=1; foo.eat_stack caller; m-=1; end } fork {|pid| while true; Process.kill 12,parent; sleep .01; end } END { STDERR.puts; foo.print_top_methods_to(STDERR) } ----------------8<--------------d�coupez-ici--------------8<---------------- matju