lib/ruby-metrics/instruments/histogram.rb in ruby-metrics-0.8.6 vs lib/ruby-metrics/instruments/histogram.rb in ruby-metrics-0.9.0

- old
+ new

@@ -1,9 +1,12 @@ +require 'ruby-metrics/statistics/uniform_sample' +require 'ruby-metrics/statistics/exponential_sample' + module Metrics module Instruments - class Histogram < Base - + class Histogram + def initialize(type = :uniform) @count = 0 case type when :uniform @sample = Metrics::Statistics::UniformSample.new @@ -14,43 +17,43 @@ @max = nil @sum = 0 @variance_s = 0 @variance_m = -1 end - + def update(value) @count += 1 @sum += value @sample.update(value) update_max(value) update_min(value) update_variance(value); end - - def clear + + def clear @sample.clear @min = nil @max = nil @sum = 0 @count = 0 @variance_m = -1 @variance_s = 0 end - + def quantiles(percentiles) # Calculated using the same logic as R and Ecxel use # as outlined by the NIST here: http://www.itl.nist.gov/div898/handbook/prc/section2/prc252.htm count = @count scores = {} values = @sample.values[0..count-1] - + percentiles.each do |pct| scores[pct] = 0.0 end - + if count > 0 - values.sort! + values.sort! percentiles.each do |pct| idx = pct * (values.length - 1) + 1.0 if idx <= 1 scores[pct] = values[0] elsif idx >= values.length @@ -60,122 +63,120 @@ upper = values[idx.to_i] scores[pct] = lower + (idx - idx.floor) * (upper - lower) end end end - + return scores end - + def update_min(value) if (@min == nil || value < @min) - @min = value + @min = value end end - + def update_max(value) if (@max == nil || value > @max) - @max = value - end + @max = value + end end - + def update_variance(value) count = @count old_m = @variance_m new_m = @variance_m + ((value - old_m) / count) new_s = @variance_s + ((value - old_m) * (value - new_m)) - + @variance_m = new_m @variance_s = new_s end - + def variance count = @count - variance_s = @variance_s - - if count <= 1 + variance_s = @variance_s + + if count <= 1 return 0.0 else return variance_s.to_f / (count - 1).to_i end end - + def count count = @count return count end - - + + def max max = @max if max != nil return max else return 0.0 end end - + def min min = @min if min != nil return min else return 0.0 end end - + def mean count = @count sum = @sum - + if count > 0 return sum / count else return 0.0 end end - - def std_dev + + def std_dev count = @count variance = self.variance() - + if count > 0 return Math.sqrt(variance) - else + else return 0.0 end end - + def values @sample.values end - - def to_json(*_) + + def as_json(*_) { - :min => self.min, + :min => self.min, :max => self.max, - :mean => self.mean, - :variance => self.variance, + :mean => self.mean, + :variance => self.variance, :percentiles => self.quantiles([0.25, 0.50, 0.75, 0.95, 0.97, 0.98, 0.99]) - }.to_json + } end - + + def to_json(*_) + as_json.to_json + end end - + class ExponentialHistogram < Histogram def initialize super(:exponential) end end - register_instrument(:exponential_histogram, ExponentialHistogram) - class UniformHistogram < Histogram def initialize super(:uniform) end end - - register_instrument(:uniform_histogram, UniformHistogram) end - end