Class: SamplingProf

Inherits:
Object
  • Object
show all
Defined in:
lib/sampling_prof.rb,
lib/sampling_prof/internal.rb

Defined Under Namespace

Classes: Sample, Sampling

Constant Summary collapse

DEFAULT_OUTPUT_FILE =
'profile.txt'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(period) ⇒ SamplingProf

Returns a new instance of SamplingProf.



50
51
52
53
54
# File 'lib/sampling_prof/internal.rb', line 50

def initialize(period)
  @period = period
  @running = false
  @sampling_thread = nil
end

Instance Attribute Details

#output_fileObject



12
13
14
# File 'lib/sampling_prof.rb', line 12

def output_file
  @output_file ||= DEFAULT_OUTPUT_FILE
end

Instance Method Details

#__start__(&block) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/sampling_prof/internal.rb', line 56

def __start__(&block)
  unless @running
    @running = true
    target = Thread.current
    @sampling_thread = Thread.start do
      sampling = Sampling.new
      loop do
        break unless @running
        sampling.process(target.backtrace_locations)
        sleep @period
      end
      block.call(sampling.result)
    end
    true
  end
end

#default_output_handlerObject



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/sampling_prof.rb', line 27

def default_output_handler
  lambda do |data|
    nodes, counts, call_graph = data
    File.open(output_file, 'w') do |f|
      nodes.each do |node|
        # node name, node id
        f.puts node.join(',')
      end
      f.puts ""
      counts.each do |count|
        # node id, count
        f.puts count.flatten.join(",")
      end
      f.puts ""
      call_graph.each do |v|
        # from node id, to node id, count
        f.puts v.flatten.join(",")
      end
    end
  end
end

#flat_report(nodes, counts) ⇒ Object



69
70
71
72
73
74
75
76
77
# File 'lib/sampling_prof.rb', line 69

def flat_report(nodes, counts)
  total = counts.map{|_,sc,tc| sc}.reduce(:+)
  reports = counts.reject{|_,sc,tc| sc == 0}.sort_by{|_,sc,tc| -sc}.map do |id, sc, tc|
    [sc, '%.2f%' % (100 * sc.to_f/total),
     tc, '%.2f%' % (100 * tc.to_f/total),
     nodes[id]]
  end
  [total, reports]
end

#profile(&block) ⇒ Object



16
17
18
19
20
21
# File 'lib/sampling_prof.rb', line 16

def profile(&block)
  start
  yield if block_given?
ensure
  stop if block_given?
end

#profiling?Boolean

Returns:

  • (Boolean)


82
83
84
# File 'lib/sampling_prof/internal.rb', line 82

def profiling?
  !!@sampling_thread
end

#report(type, output = $stdout) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/sampling_prof.rb', line 49

def report(type, output=$stdout)
  nodes, counts, call_graph = File.read(output_file).split("\n\n")
  nodes = nodes.split("\n").inject({}) do |ret, l|
    n, i = l.split(',')
    ret[i.to_i] = n
    ret
  end

  counts = counts.split("\n").map do |l|
    l.split(',').map(&:to_i)
  end
  total_samples, report = flat_report(nodes, counts)

  output.puts "total samples: #{total_samples}"
  output.puts "self\t%\ttotal\t%\tname"
  report.first(20).each do |v|
    output.puts v.join("\t")
  end
end

#start(handler = default_output_handler) ⇒ Object



23
24
25
# File 'lib/sampling_prof.rb', line 23

def start(handler=default_output_handler)
  __start__(&handler)
end

#stopObject



73
74
75
76
77
78
79
80
# File 'lib/sampling_prof/internal.rb', line 73

def stop
  if @running
    @running = false
    @sampling_thread.join
    @sampling_thread = nil
    true
  end
end