* io.c (rb_open_file): encoding in mode string was ignored if perm is
[ruby-svn.git] / lib / profiler.rb
bloba4b88890933d806bbec9c7f06c88ed84feeaf8fc
1 module Profiler__
2   # internal values
3   @@start = @@stack = @@map = nil
4   PROFILE_PROC = proc{|event, file, line, id, binding, klass|
5     case event
6     when "call", "c-call"
7       now = Process.times[0]
8       @@stack.push [now, 0.0]
9     when "return", "c-return"
10       now = Process.times[0]
11       key = [klass, id]
12       if tick = @@stack.pop
13         data = (@@map[key] ||= [0, 0.0, 0.0, key])
14         data[0] += 1
15         cost = now - tick[0]
16         data[1] += cost
17         data[2] += cost - tick[1]
18         @@stack[-1][1] += cost if @@stack[-1]
19       end
20     end
21   }
22 module_function
23   def start_profile
24     @@start = Process.times[0]
25     @@stack = []
26     @@map = {}
27     set_trace_func PROFILE_PROC
28   end
29   def stop_profile
30     set_trace_func nil
31   end
32   def print_profile(f)
33     stop_profile
34     total = Process.times[0] - @@start
35     if total == 0 then total = 0.01 end
36     data = @@map.values
37     data = data.sort_by{|x| -x[2]}
38     sum = 0
39     f.printf "  %%   cumulative   self              self     total\n"
40     f.printf " time   seconds   seconds    calls  ms/call  ms/call  name\n"
41     for d in data
42       sum += d[2]
43       f.printf "%6.2f %8.2f  %8.2f %8d ", d[2]/total*100, sum, d[2], d[0]
44       f.printf "%8.2f %8.2f  %s\n", d[2]*1000/d[0], d[1]*1000/d[0], get_name(*d[3])
45     end
46     f.printf "%6.2f %8.2f  %8.2f %8d ", 0.0, total, 0.0, 1     # ???
47     f.printf "%8.2f %8.2f  %s\n", 0.0, total*1000, "#toplevel" # ???
48   end
49   def get_name(klass, id)
50     name = klass.to_s || ""
51     if klass.kind_of? Class
52       name += "#"
53     else
54       name += "."
55     end
56     name + id.id2name
57   end
58   private :get_name
59 end