One gave an idea,
But none had written the code.
Here, Hear, Here it is.


SProfile.rb
----------------8<--------------d˝─oupez-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˝─oupez-ici--------------8<----------------
matju