Class: MultiMeasure

Inherits:
Object
  • Object
show all
Defined in:
lib/multi_measure.rb,
lib/multi_measure/config.rb,
lib/multi_measure/macros.rb,
lib/multi_measure/version.rb,
lib/multi_measure/middleware.rb,
lib/multi_measure/math_helpers.rb,
lib/multi_measure/null_measurer.rb,
lib/multi_measure/thread_safe_hash.rb,
lib/multi_measure/measurement_state.rb

Defined Under Namespace

Modules: Config, Macros, MathHelpers Classes: MeasurementState, Middleware, NullMeasurer, ThreadSafeHash

Constant Summary collapse

VERSION =
"0.1.1"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeMultiMeasure

Returns a new instance of MultiMeasure.



71
72
73
# File 'lib/multi_measure.rb', line 71

def initialize
  @measurements = ThreadSafeHash.new
end

Class Method Details

.configObject



32
33
34
# File 'lib/multi_measure.rb', line 32

def config
  @config ||= default_config
end

.configure {|config| ... } ⇒ Object

Yields:



13
14
15
16
# File 'lib/multi_measure.rb', line 13

def configure
  yield config
  @config = config
end

.current_measurementsObject



54
55
56
# File 'lib/multi_measure.rb', line 54

def current_measurements
  instance.current_measurements
end

.default_configObject



18
19
20
21
22
23
24
25
26
# File 'lib/multi_measure.rb', line 18

def default_config
  MultiMeasure::Config.build_from(
    output_prefix: "MULTI_MEASURE_TOTAL",
    write_to: STDOUT,
    middleware: {
      env_var: "MULTI_MEASURE_ENABLED"
    }
  )
end

.doneObject



44
45
46
47
# File 'lib/multi_measure.rb', line 44

def done
  instance.print_all_measurements
  reset
end

.measure(*names, &block) ⇒ Object



58
59
60
# File 'lib/multi_measure.rb', line 58

def measure(*names, &block)
  instance.measure(*names, &block)
end

.resetObject



40
41
42
# File 'lib/multi_measure.rb', line 40

def reset
  Thread.current[STORE_KEY] = nil
end

.set_default_configObject



28
29
30
# File 'lib/multi_measure.rb', line 28

def set_default_config
  @config = default_config
end

.startObject



36
37
38
# File 'lib/multi_measure.rb', line 36

def start
  Thread.current[STORE_KEY] = new
end

.track_measurementsObject



49
50
51
52
# File 'lib/multi_measure.rb', line 49

def track_measurements
  start
  yield.tap { done }
end

Instance Method Details

#current_measurementsObject



94
95
96
# File 'lib/multi_measure.rb', line 94

def current_measurements
  measurements.to_normal_hash
end

#measure(*names) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/multi_measure.rb', line 75

def measure(*names)
  return_value = nil

  state = MeasurementState.new

  time = Benchmark.realtime do
    return_value = yield state
  end

  if state.track_measurement?
    names.each do |name|
      measurements[name] ||= []
      measurements[name] << time
    end
  end

  return_value
end


98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/multi_measure.rb', line 98

def print_all_measurements
  longest_key_length = 0
  measurements.each do |key, _value|
    if key.length > longest_key_length
      longest_key_length = key.length
    end
  end

  longest_time_length = 0
  measurements.each do |_key, times|
    length = to_ms(times.sum).to_s.length
    if length > longest_time_length
      longest_time_length = length
    end
  end

  sorted_measurements = measurements.sort_by { |_key, times| times.sum }
  sorted_measurements.each do |key, times|
    key = key.rjust(longest_key_length)
    time = to_ms(times.sum).to_s.rjust(longest_time_length)

    std = MathHelpers.standard_deviation(times.map { |t| to_ms(t) }).round(2)
    extra_info = "(+/- #{std}ms, #{times.size} calls)"

    write_to_io "#{key} #{time}ms #{extra_info}"
  end
end