Class: Logging::Stats::Sampler

Inherits:
Object
  • Object
show all
Defined in:
lib/logging/stats.rb

Overview

A very simple little class for doing some basic fast statistics sampling. You feed it either samples of numeric data you want measured or you call Sampler#tick to get it to add a time delta between the last time you called it. When you’re done either call sum, sumsq, num, min, max, mean or sd to get the information. The other option is to just call to_s and see everything.

It does all of this very fast and doesn’t take up any memory since the samples are not stored but instead all the values are calculated on the fly.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ Sampler

Create a new sampler.



22
23
24
25
# File 'lib/logging/stats.rb', line 22

def initialize( name )
  @name = name
  reset
end

Instance Attribute Details

#lastObject (readonly)

Returns the value of attribute last.



18
19
20
# File 'lib/logging/stats.rb', line 18

def last
  @last
end

#maxObject (readonly)

Returns the value of attribute max.



18
19
20
# File 'lib/logging/stats.rb', line 18

def max
  @max
end

#minObject (readonly)

Returns the value of attribute min.



18
19
20
# File 'lib/logging/stats.rb', line 18

def min
  @min
end

#nameObject (readonly)

Returns the value of attribute name.



18
19
20
# File 'lib/logging/stats.rb', line 18

def name
  @name
end

#numObject (readonly)

Returns the value of attribute num.



18
19
20
# File 'lib/logging/stats.rb', line 18

def num
  @num
end

#sumObject (readonly)

Returns the value of attribute sum.



18
19
20
# File 'lib/logging/stats.rb', line 18

def sum
  @sum
end

#sumsqObject (readonly)

Returns the value of attribute sumsq.



18
19
20
# File 'lib/logging/stats.rb', line 18

def sumsq
  @sumsq
end

Class Method Details

.keysObject

Class method that returns the headers that a CSV file would have for the values that this stats object is using.



88
89
90
# File 'lib/logging/stats.rb', line 88

def self.keys
  %w[name sum sumsq num mean sd min max]
end

Instance Method Details

#coalesce(other) ⇒ Object

Coalesce the statistics from the other sampler into this one. The other sampler is not modified by this method.

Coalescing the same two samplers multiple times should only be done if one of the samplers is reset between calls to this method. Otherwise statistics will be counted multiple times.



47
48
49
50
51
52
53
54
55
56
# File 'lib/logging/stats.rb', line 47

def coalesce( other )
  @sum += other.sum
  @sumsq += other.sumsq
  if other.num > 0
    @min = other.min if @min > other.min
    @max = other.max if @max < other.max
    @last = other.last
  end
  @num += other.num
end

#markObject

You can just call tick repeatedly if you need the delta times between a set of sample periods, but many times you actually want to sample how long something takes between a start/end period. Call mark at the beginning and then tick at the end you’ll get this kind of measurement. Don’t mix mark/tick and tick sampling together or the measurement will be meaningless.



124
125
126
# File 'lib/logging/stats.rb', line 124

def mark
  @last_time = Time.now.to_f
end

#meanObject

Calculates and returns the mean for the data passed so far.



99
100
101
102
# File 'lib/logging/stats.rb', line 99

def mean
  return 0.0 if num < 1
  sum / num
end

#resetObject

Resets the internal counters so you can start sampling again.



29
30
31
32
33
34
35
36
37
38
# File 'lib/logging/stats.rb', line 29

def reset
  @sum = 0.0
  @sumsq = 0.0
  @num = 0
  @min = 0.0
  @max = 0.0
  @last = nil
  @last_time = Time.now.to_f
  self
end

#sample(s) ⇒ Object

Adds a sampling to the calculations.



60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/logging/stats.rb', line 60

def sample( s )
  @sum += s
  @sumsq += s * s
  if @num == 0
    @min = @max = s
  else
    @min = s if @min > s
    @max = s if @max < s
  end
  @num += 1
  @last = s
end

#sdObject

Calculates the standard deviation of the data so far.



106
107
108
109
110
111
112
113
114
115
# File 'lib/logging/stats.rb', line 106

def sd
  return 0.0 if num < 2

  # (sqrt( ((s).sumsq - ( (s).sum * (s).sum / (s).num)) / ((s).num-1) ))
  begin
    return Math.sqrt( (sumsq - ( sum * sum / num)) / (num-1) )
  rescue Errno::EDOM
    return 0.0
  end
end

#tickObject

Adds a time delta between now and the last time you called this. This will give you the average time between two activities.

An example is:

t = Sampler.new("do_stuff")
10000.times { do_stuff(); t.tick }
t.dump("time")


137
138
139
140
141
# File 'lib/logging/stats.rb', line 137

def tick
  now = Time.now.to_f
  sample(now - @last_time)
  @last_time = now
end

#to_aObject

An array of the values: [name,sum,sumsq,num,mean,sd,min,max]



81
82
83
# File 'lib/logging/stats.rb', line 81

def to_a
  [name, sum, sumsq, num, mean, sd, min, max]
end

#to_hashObject



92
93
94
95
# File 'lib/logging/stats.rb', line 92

def to_hash
  {:name => name, :sum => sum, :sumsq => sumsq, :num => num,
   :mean => mean, :sd => sd, :min => min, :max => max}
end

#to_sObject

Returns statistics in a common format.



75
76
77
# File 'lib/logging/stats.rb', line 75

def to_s
  "[%s]: SUM=%0.6f, SUMSQ=%0.6f, NUM=%d, MEAN=%0.6f, SD=%0.6f, MIN=%0.6f, MAX=%0.6f" % to_a
end