Class: SamplingProf

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

Defined Under Namespace

Classes: Sampling

Constant Summary collapse

DEFAULT_OUTPUT_FILE =
'profile.txt'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args, &output_handler) ⇒ SamplingProf

options:

sampling_interval: default to 0.1 second
profiling_threshold: default to 0 second
&output_handler: default to write into output_file


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

def initialize(*args, &output_handler)
  self.sampling_interval = args[0] || 0.1
  self.profiling_threshold = args[1] || 0
  self.output_handler = block_given? ? output_handler : default_output_handler
  internal_initialize if respond_to?(:internal_initialize)
end

Instance Attribute Details

#output_fileObject



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

def output_file
  @output_file ||= DEFAULT_OUTPUT_FILE
end

#output_handlerObject

Returns the value of attribute output_handler.



63
64
65
# File 'lib/sampling_prof/internal.rb', line 63

def output_handler
  @output_handler
end

#profiling_thresholdObject

Returns the value of attribute profiling_threshold.



63
64
65
# File 'lib/sampling_prof/internal.rb', line 63

def profiling_threshold
  @profiling_threshold
end

#sampling_intervalObject

Returns the value of attribute sampling_interval.



63
64
65
# File 'lib/sampling_prof/internal.rb', line 63

def sampling_interval
  @sampling_interval
end

Instance Method Details

#default_output_handlerObject



34
35
36
37
38
39
40
# File 'lib/sampling_prof.rb', line 34

def default_output_handler
  lambda do |data|
    File.open(output_file, 'w') do |f|
      f.write(data)
    end
  end
end

#flat_report(nodes, counts) ⇒ Object



63
64
65
66
67
68
69
70
71
# File 'lib/sampling_prof.rb', line 63

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

#internal_initializeObject



65
66
67
68
# File 'lib/sampling_prof/internal.rb', line 65

def internal_initialize
  @samplings = {}
  start_sampling_thread
end

#profile(&block) ⇒ Object



27
28
29
30
31
32
# File 'lib/sampling_prof.rb', line 27

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

#profiling?Boolean

Returns:

  • (Boolean)


97
98
99
# File 'lib/sampling_prof/internal.rb', line 97

def profiling?
  !!@sampling_thread && @samplings.has_key?(Thread.current)
end

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



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/sampling_prof.rb', line 42

def report(type, output=$stdout)
  runtime, 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 "runtime: #{runtime.to_f/1000} secs"
  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

#startObject



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

def start
  unless @samplings.has_key?(Thread.current)
    @samplings[Thread.current] = Sampling.new
    true
  end
end

#stopObject



77
78
79
80
81
82
83
84
85
86
# File 'lib/sampling_prof/internal.rb', line 77

def stop
  if @running
    if sampling = @samplings.delete(Thread.current)
      if sampling.sampling_data?
        @output_handler.call(sampling.result)
      end
      true
    end
  end
end

#terminateObject



88
89
90
91
92
93
94
95
# File 'lib/sampling_prof/internal.rb', line 88

def terminate
  return false unless @running
  @running = false
  @sampling_thread.join
  @sampling_thread = nil
  @samplings = {}
  true
end