hitimes 1.3.0-x64-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +57 -0
  3. data/HISTORY.md +124 -0
  4. data/LICENSE +16 -0
  5. data/Manifest.txt +44 -0
  6. data/README.md +200 -0
  7. data/Rakefile +28 -0
  8. data/examples/benchmarks.rb +113 -0
  9. data/examples/stats.rb +31 -0
  10. data/ext/hitimes/c/extconf.rb +24 -0
  11. data/ext/hitimes/c/hitimes.c +37 -0
  12. data/ext/hitimes/c/hitimes_instant_clock_gettime.c +28 -0
  13. data/ext/hitimes/c/hitimes_instant_osx.c +45 -0
  14. data/ext/hitimes/c/hitimes_instant_windows.c +27 -0
  15. data/ext/hitimes/c/hitimes_interval.c +370 -0
  16. data/ext/hitimes/c/hitimes_interval.h +73 -0
  17. data/ext/hitimes/c/hitimes_stats.c +269 -0
  18. data/ext/hitimes/c/hitimes_stats.h +30 -0
  19. data/ext/hitimes/java/src/hitimes/Hitimes.java +66 -0
  20. data/ext/hitimes/java/src/hitimes/HitimesInterval.java +176 -0
  21. data/ext/hitimes/java/src/hitimes/HitimesService.java +16 -0
  22. data/ext/hitimes/java/src/hitimes/HitimesStats.java +112 -0
  23. data/lib/hitimes.rb +66 -0
  24. data/lib/hitimes/2.0/hitimes.so +0 -0
  25. data/lib/hitimes/2.1/hitimes.so +0 -0
  26. data/lib/hitimes/2.2/hitimes.so +0 -0
  27. data/lib/hitimes/2.3/hitimes.so +0 -0
  28. data/lib/hitimes/2.4/hitimes.so +0 -0
  29. data/lib/hitimes/2.5/hitimes.so +0 -0
  30. data/lib/hitimes/metric.rb +118 -0
  31. data/lib/hitimes/mutexed_stats.rb +32 -0
  32. data/lib/hitimes/paths.rb +53 -0
  33. data/lib/hitimes/stats.rb +58 -0
  34. data/lib/hitimes/timed_metric.rb +176 -0
  35. data/lib/hitimes/timed_value_metric.rb +233 -0
  36. data/lib/hitimes/value_metric.rb +71 -0
  37. data/lib/hitimes/version.rb +8 -0
  38. data/spec/hitimes_spec.rb +24 -0
  39. data/spec/interval_spec.rb +136 -0
  40. data/spec/metric_spec.rb +28 -0
  41. data/spec/mutex_stats_spec.rb +36 -0
  42. data/spec/paths_spec.rb +11 -0
  43. data/spec/spec_helper.rb +11 -0
  44. data/spec/stats_spec.rb +98 -0
  45. data/spec/timed_metric_spec.rb +155 -0
  46. data/spec/timed_value_metric_spec.rb +171 -0
  47. data/spec/value_metric_spec.rb +108 -0
  48. data/spec/version_spec.rb +7 -0
  49. data/tasks/default.rake +242 -0
  50. data/tasks/extension.rake +38 -0
  51. data/tasks/this.rb +208 -0
  52. metadata +216 -0
@@ -0,0 +1,176 @@
1
+ #--
2
+ # Copyright (c) 2008, 2009 Jeremy Hinegardner
3
+ # All rights reserved. See LICENSE and/or COPYING for details.
4
+ #++
5
+
6
+ require 'forwardable'
7
+ module Hitimes
8
+ #
9
+ # A TimedMetric holds the metrics on how long it takes to do something. For
10
+ # example, measuring how long a method takes to operate.
11
+ #
12
+ # tm = TimedMetric.new( 'my-method' )
13
+ #
14
+ # 200.times do
15
+ # my_method_result = tm.measure do
16
+ # my_method( ... )
17
+ # end
18
+ # end
19
+ #
20
+ # puts "#{ tm.name } operated at a rate of #{ tm.rate } calls per second"
21
+ #
22
+ # Since TimedMetric is a child class of Metric make sure to look at the
23
+ # Metric API also.
24
+ #
25
+ # A TimedMetric measures the execution time of an option with the Interval
26
+ # class.
27
+ #
28
+ # A TimedMetric contains a Stats object, therefore TimedMetric has +count+, +max+,
29
+ # +mean+, +min+, +rate+, +stddev+, +sum+, +sumsq+ methods that delegate to that Stats
30
+ # object for convenience.
31
+ #
32
+ #
33
+ class TimedMetric < Metric
34
+ # holds all the statistics
35
+ attr_reader :stats
36
+
37
+ class << TimedMetric
38
+ #
39
+ # :call-seq:
40
+ # TimedMetric.now -> TimedMetric
41
+ #
42
+ # Return a TimedMetric that has been started
43
+ #
44
+ def now( name, additional_data = {} )
45
+ t = TimedMetric.new( name, additional_data )
46
+ t.start
47
+ return t
48
+ end
49
+ end
50
+
51
+ #
52
+ # :call-seq:
53
+ # TimedMetric.new( 'name') -> TimedMetric
54
+ # TimedMetric.new( 'name', 'other' => 'data') -> TimedMetric
55
+ #
56
+ # Create a new TimedMetric giving it a name and additional data.
57
+ # +additional_data+ may be anything that follows the +to_hash+ protocol
58
+ #
59
+ def initialize( name, additional_data = {} )
60
+ super( name, additional_data )
61
+ @stats = Stats.new
62
+ @current_interval = Interval.new
63
+ end
64
+
65
+ #
66
+ # :call-seq:
67
+ # timed_metric.running? -> true or false
68
+ #
69
+ # return whether or not the timer is currently running.
70
+ #
71
+ def running?
72
+ @current_interval.running?
73
+ end
74
+
75
+ #
76
+ # :call-seq:
77
+ # timed_metric.start -> nil
78
+ #
79
+ # Start the current metric, if the current metric is already started, then
80
+ # this is a noop.
81
+ #
82
+ def start
83
+ if not @current_interval.running? then
84
+ @current_interval.start
85
+ @sampling_start_time ||= self.utc_microseconds()
86
+ @sampling_start_interval ||= Interval.now
87
+ end
88
+ nil
89
+ end
90
+
91
+ #
92
+ # :call-seq:
93
+ # timed_metric.stop -> Float or nil
94
+ #
95
+ # Stop the current metric. This updates the stats and removes the current
96
+ # interval. If the timer was stopped then the duration of the last Interval
97
+ # is returned. If the timer was already stopped then false is returned and
98
+ # no stats are updated.
99
+ #
100
+ def stop
101
+ if @current_interval.running? then
102
+ d = @current_interval.stop
103
+ @stats.update( d )
104
+ @current_interval = Interval.new
105
+
106
+ # update the length of time we have been sampling
107
+ @sampling_delta = @sampling_start_interval.duration_so_far
108
+
109
+ return d
110
+ end
111
+ return false
112
+ end
113
+
114
+ #
115
+ # :call-seq:
116
+ # timed_metric.measure { ... } -> Object
117
+ #
118
+ # Measure the execution of a block and add those stats to the running stats.
119
+ # The return value is the return value of the block
120
+ #
121
+ def measure( &block )
122
+ return_value = nil
123
+ begin
124
+ start
125
+ return_value = yield
126
+ ensure
127
+ stop
128
+ end
129
+ return return_value
130
+ end
131
+
132
+ #
133
+ # :call-seq:
134
+ # timed_metric.split -> Float
135
+ #
136
+ # Split the current TimedMetric. Essentially, mark a split time. This means
137
+ # stop the current interval and create a new interval, but make sure
138
+ # that the new interval lines up exactly, timewise, behind the previous
139
+ # interval.
140
+ #
141
+ # If the timer is running, then split returns the duration of the previous
142
+ # interval, i.e. the split-time. If the timer is not running, nothing
143
+ # happens and false is returned.
144
+ #
145
+ def split
146
+ if @current_interval.running? then
147
+ next_interval = @current_interval.split
148
+ d = @current_interval.duration
149
+ @stats.update( d )
150
+ @current_interval = next_interval
151
+ return d
152
+ end
153
+ return false
154
+ end
155
+
156
+ #
157
+ # :call-seq:
158
+ # metric.to_hash -> Hash
159
+ #
160
+ # Convert the metric to a hash
161
+ #
162
+ def to_hash
163
+ h = super
164
+ Stats::STATS.each do |s|
165
+ h[s] = self.send( s )
166
+ end
167
+ return h
168
+ end
169
+
170
+
171
+ # forward appropriate calls directly to the stats object
172
+ extend Forwardable
173
+ def_delegators :@stats, :count, :max, :mean, :min, :rate, :stddev, :sum, :sumsq
174
+ alias :duration :sum
175
+ end
176
+ end
@@ -0,0 +1,233 @@
1
+ #--
2
+ # Copyright (c) 2008, 2009 Jeremy Hinegardner
3
+ # All rights reserved. See LICENSE and/or COPYING for details.
4
+ #++
5
+
6
+ module Hitimes
7
+ #
8
+ # A TimedValueMetric holds the metrics on how long it takes to do a batch of something.
9
+ # something. For measuring how long a method takes to operate on N items.
10
+ #
11
+ # tm = TimedValueMetric.new( 'my-batch-method' )
12
+ #
13
+ # 42.times do
14
+ # tm.start
15
+ # number_of_items_processed = do_something
16
+ # tm.stop( number_of_items_processed )
17
+ # end
18
+ #
19
+ # puts "#{ tm.name } operated at a rate of #{ tm.rate } calls per second"
20
+ #
21
+ # TimedValueMetric combines the usefulness of a ValueMetric and a TimedMetric.
22
+ # The stats are available for both the time it took to do the operation and
23
+ # the sizes of the batches that were run.
24
+ #
25
+ # A TimedValueMetric keeps track of both the time it took to do an operation
26
+ # and the size of the batch that was operated on. These metrics are kept
27
+ # separately as +timed_stats+ and +value_stats+ accessors.
28
+ #
29
+ class TimedValueMetric < Metric
30
+ # holds all the Timed statistics
31
+ attr_reader :timed_stats
32
+
33
+ # holds all the Value statistics
34
+ attr_reader :value_stats
35
+
36
+ class << TimedValueMetric
37
+ #
38
+ # :call-seq:
39
+ # TimedValueMetric.now( 'name' ) -> TimedValueMetric
40
+ #
41
+ # Return a TimedValueMetric that has been started
42
+ #
43
+ def now( name, additional_data = {} )
44
+ t = TimedValueMetric.new( name, additional_data )
45
+ t.start
46
+ return t
47
+ end
48
+ end
49
+
50
+ #
51
+ # :call-seq:
52
+ # TimedValueMetric.new( 'name') -> TimedValueMetric
53
+ # TimedValueMetric.new( 'name', 'other' => 'data') -> TimedValueMetric
54
+ #
55
+ # Create a new TimedValueMetric giving it a name and additional data.
56
+ # +additional_data+ may be anything that follows the +to_hash+ protocol
57
+ #
58
+ def initialize( name, additional_data = {} )
59
+ super( name, additional_data )
60
+ @timed_stats = Stats.new
61
+ @value_stats = Stats.new
62
+ @current_interval = Interval.new
63
+ end
64
+
65
+ #
66
+ # :call-seq:
67
+ # timed_value_metric.running? -> true or false
68
+ #
69
+ # return whether or not the metric is currently timing something.
70
+ #
71
+ def running?
72
+ @current_interval.running?
73
+ end
74
+
75
+ #
76
+ # :call-seq:
77
+ # timed_value_metric.start -> nil
78
+ #
79
+ # Start the current timer, if the current timer is already started, then
80
+ # this is a noop.
81
+ #
82
+ def start
83
+ if not @current_interval.running? then
84
+ @current_interval.start
85
+ @sampling_start_time ||= self.utc_microseconds()
86
+ @sampling_start_interval ||= Interval.now
87
+ end
88
+ nil
89
+ end
90
+
91
+ #
92
+ # :call-seq:
93
+ # timed_value_metric.stop( count ) -> Float or nil
94
+ #
95
+ # Stop the current metric. The +count+ parameter must be a
96
+ # value to update to the _value_ portion of the TimedValueMetric. Generally
97
+ # this is probably the number of things that were operated upon since
98
+ # +start+ was invoked.
99
+ #
100
+ # This updates both the +value_stats+ and +timed_stats+ stats and removes
101
+ # the current interval. If the metric is stopped then the duration of the
102
+ # last Interval is returned. If the metric was already stopped before this
103
+ # call, then false is returned and no stats are updated.
104
+ #
105
+ #
106
+ def stop( value )
107
+ if @current_interval.running? then
108
+ d = @current_interval.stop
109
+ @timed_stats.update( d )
110
+ @current_interval = Interval.new
111
+ @value_stats.update( value )
112
+
113
+ # update the lenght of time we have been sampling
114
+ @sampling_delta = @sampling_start_interval.duration_so_far
115
+
116
+ return d
117
+ end
118
+ return false
119
+ end
120
+
121
+ #
122
+ # :call-seq:
123
+ # timed_value_metric.measure( value ) { ... } -> Object
124
+ #
125
+ # Measure the execution of a block and add those stats to the running stats.
126
+ # The return value is the return value of the block. A value must be passed
127
+ # into +measure+ to update the +value_stats+ portion of the TimedValueMetric.
128
+ #
129
+ def measure( value, &block )
130
+ return_value = nil
131
+ begin
132
+ start
133
+ return_value = yield
134
+ ensure
135
+ stop( value )
136
+ end
137
+ return return_value
138
+ end
139
+
140
+ #
141
+ # :call-seq:
142
+ # timed_value_metric.split( value ) -> Float
143
+ #
144
+ # Split the current metric. Essentially, mark a split time. This means
145
+ # stop the current interval, with the givein +value+ and create a new
146
+ # interval, but make sure that the new interval lines up exactly, timewise,
147
+ # behind the previous interval.
148
+ #
149
+ # If the metric is running, then split returns the duration of the previous
150
+ # interval, i.e. the split-time. If the metric is not running, nothing
151
+ # happens, no stats are updated, and false is returned.
152
+ #
153
+ #
154
+ def split( value )
155
+ if @current_interval.running? then
156
+ next_interval = @current_interval.split
157
+ d = @current_interval.duration
158
+ @timed_stats.update( d )
159
+ @value_stats.update( value )
160
+ @current_interval = next_interval
161
+ return d
162
+ end
163
+ return false
164
+ end
165
+
166
+ #
167
+ # :call-seq:
168
+ # timed_value_metric.duration -> Float
169
+ #
170
+ # The duration of measured time from the metric.
171
+ #
172
+ def duration
173
+ @timed_stats.sum
174
+ end
175
+
176
+ #
177
+ # :call-seq:
178
+ # timed_value_metric.unit_count -> Float
179
+ #
180
+ # The sum of all values passed to +stop+ or +skip+ or +measure+
181
+ #
182
+ def unit_count
183
+ @value_stats.sum
184
+ end
185
+
186
+ #
187
+ # :call-seq:
188
+ # timed_value_metric.rate -> Float
189
+ #
190
+ # Rate in the context of the TimedValueMetric is different than the
191
+ # TimedMetric. In the TimedValueMetric, each measurement of time is
192
+ # associated with a quantity of things done during that unit of time. So
193
+ # the +rate+ for a TimedValueMetric is the (sum of all quantities sampled) /
194
+ # ( sum of all durations measured )
195
+ #
196
+ # For example, say you were measuring, using a TimedValueMetric batch jobs
197
+ # that had individual units of work.
198
+ #
199
+ # tvm = TimedValueMetric.new( 'some-batch' )
200
+ # tvm.start
201
+ # # process a batch of 12 units
202
+ # duration1 = tvm.stop( 12 )
203
+ #
204
+ # tvm.start
205
+ # # process a larger batch of 42 units
206
+ # duration2 = tvm.stop( 42 )
207
+ #
208
+ # At this point the rate of units per second is calculated as ( 12 + 42 ) / ( duration1 + duration2 )
209
+ #
210
+ # some_batch_rate = tvm.rate # returns ( 34 / ( duration1+duration2 ) )
211
+ #
212
+ def rate
213
+ @value_stats.sum / @timed_stats.sum
214
+ end
215
+
216
+ #
217
+ # :call-seq:
218
+ # metric.to_hash -> Hash
219
+ #
220
+ # Convert the metric to a hash
221
+ #
222
+ def to_hash
223
+ h = super
224
+ h['timed_stats'] = @timed_stats.to_hash
225
+ h['value_stats'] = @value_stats.to_hash( Stats::STATS - %w[ rate ] )
226
+ h['rate'] = self.rate
227
+ h['unit_count'] = self.unit_count
228
+ return h
229
+ end
230
+
231
+
232
+ end
233
+ end
@@ -0,0 +1,71 @@
1
+ #--
2
+ # Copyright (c) 2008, 2009 Jeremy Hinegardner
3
+ # All rights reserved. See LICENSE and/or COPYING for details.
4
+ #++
5
+
6
+ require 'forwardable'
7
+ module Hitimes
8
+ #
9
+ # A ValueMetric holds the data from measuring a single value over a period of
10
+ # time. In most cases this may be a single measurement at a single point in
11
+ # time.
12
+ #
13
+ # A good example of a ValueMetric is measuring the number of items in a queue.
14
+ #
15
+ # A ValueMetric contains a Stats object, therefore ValueMetric has +count+, +max+,
16
+ # +mean+, +min+, +stddev+, +sum+, +sumsq+ methods that delegate to that Stats
17
+ # object for convenience.
18
+ #
19
+ class ValueMetric < Metric
20
+
21
+ # holds all the statistics
22
+ attr_reader :stats
23
+
24
+ #
25
+ # :call-seq:
26
+ # ValueMetric.new( 'my_metric' ) -> ValueMetric
27
+ # ValueMetric.new( 'my_metric', 'foo' => 'bar', 'this' => 42 ) -> ValueMetric
28
+ #
29
+ # Create a new ValueMetric giving it a name and additional data.
30
+ # +additional_data+ may be anything that follows the +to_hash+ protocol.
31
+ #
32
+ def initialize( name, additional_data = {} )
33
+ super( name, additional_data )
34
+ @stats = Stats.new
35
+ end
36
+
37
+ #
38
+ # :call-seq:
39
+ # metric.measure( value ) -> Float
40
+ #
41
+ # Give the +value+ as the measurement to the metric. The value is returned
42
+ #
43
+ def measure( value )
44
+ @sampling_start_time ||= self.utc_microseconds()
45
+ @sampling_start_interval ||= Interval.now
46
+
47
+ @stats.update( value )
48
+
49
+ # update the length of time we have been sampling
50
+ @sampling_delta = @sampling_start_interval.duration_so_far
51
+ end
52
+
53
+ #
54
+ # :call-seq:
55
+ # metric.to_hash -> Hash
56
+ #
57
+ # Convert the metric to a hash
58
+ #
59
+ def to_hash
60
+ h = super
61
+ (Stats::STATS - %w[ rate ]).each do |s|
62
+ h[s] = self.send( s )
63
+ end
64
+ return h
65
+ end
66
+
67
+ # forward appropriate calls directly to the stats object
68
+ extend Forwardable
69
+ def_delegators :@stats, :count, :max, :mean, :min, :stddev, :sum, :sumsq
70
+ end
71
+ end