hitimes 1.0.4-x86-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 (46) hide show
  1. data/HISTORY +60 -0
  2. data/LICENSE +13 -0
  3. data/README +134 -0
  4. data/Rakefile +66 -0
  5. data/examples/benchmarks.rb +113 -0
  6. data/examples/stats.rb +31 -0
  7. data/ext/hitimes/extconf.rb +17 -0
  8. data/ext/hitimes/hitimes_ext.c +21 -0
  9. data/ext/hitimes/hitimes_instant_clock_gettime.c +28 -0
  10. data/ext/hitimes/hitimes_instant_osx.c +16 -0
  11. data/ext/hitimes/hitimes_instant_windows.c +27 -0
  12. data/ext/hitimes/hitimes_interval.c +362 -0
  13. data/ext/hitimes/hitimes_interval.h +73 -0
  14. data/ext/hitimes/hitimes_stats.c +269 -0
  15. data/ext/hitimes/hitimes_stats.h +30 -0
  16. data/gemspec.rb +60 -0
  17. data/lib/hitimes.rb +31 -0
  18. data/lib/hitimes/1.8/hitimes_ext.so +0 -0
  19. data/lib/hitimes/1.9/hitimes_ext.so +0 -0
  20. data/lib/hitimes/metric.rb +112 -0
  21. data/lib/hitimes/mutexed_stats.rb +28 -0
  22. data/lib/hitimes/paths.rb +53 -0
  23. data/lib/hitimes/stats.rb +54 -0
  24. data/lib/hitimes/timed_metric.rb +177 -0
  25. data/lib/hitimes/timed_value_metric.rb +235 -0
  26. data/lib/hitimes/value_metric.rb +72 -0
  27. data/lib/hitimes/version.rb +57 -0
  28. data/spec/interval_spec.rb +133 -0
  29. data/spec/metric_spec.rb +30 -0
  30. data/spec/mutex_stats_spec.rb +34 -0
  31. data/spec/paths_spec.rb +13 -0
  32. data/spec/spec_helper.rb +5 -0
  33. data/spec/stats_spec.rb +100 -0
  34. data/spec/timed_metric_spec.rb +155 -0
  35. data/spec/timed_value_metric_spec.rb +172 -0
  36. data/spec/value_metric_spec.rb +110 -0
  37. data/spec/version_spec.rb +33 -0
  38. data/tasks/announce.rake +42 -0
  39. data/tasks/config.rb +108 -0
  40. data/tasks/distribution.rake +77 -0
  41. data/tasks/documentation.rake +32 -0
  42. data/tasks/extension.rake +92 -0
  43. data/tasks/rspec.rake +31 -0
  44. data/tasks/rubyforge.rake +55 -0
  45. data/tasks/utils.rb +80 -0
  46. metadata +150 -0
@@ -0,0 +1,155 @@
1
+ require File.expand_path( File.join( File.dirname( __FILE__ ), "spec_helper.rb" ) )
2
+
3
+ require 'hitimes/timed_metric'
4
+
5
+ describe Hitimes::TimedMetric do
6
+ before( :each ) do
7
+ @tm = Hitimes::TimedMetric.new( 'test-timed-metric' )
8
+ end
9
+
10
+ it "knows if it is running or not" do
11
+ @tm.should_not be_running
12
+ @tm.start
13
+ @tm.should be_running
14
+ @tm.stop
15
+ @tm.should_not be_running
16
+ end
17
+
18
+ it "#split returns the last duration and the timer is still running" do
19
+ @tm.start
20
+ d = @tm.split
21
+ @tm.should be_running
22
+ d.should > 0
23
+ @tm.count.should == 1
24
+ @tm.duration.should == d
25
+ end
26
+
27
+ it "#stop returns false if called more than once in a row" do
28
+ @tm.start
29
+ @tm.stop.should > 0
30
+ @tm.stop.should == false
31
+ end
32
+
33
+ it "does not count a currently running interval as an interval in calculations" do
34
+ @tm.start
35
+ @tm.count.should == 0
36
+ @tm.split
37
+ @tm.count.should == 1
38
+ end
39
+
40
+ it "#split called on a stopped timer does nothing" do
41
+ @tm.start
42
+ @tm.stop
43
+ @tm.split.should == false
44
+ end
45
+
46
+ it "calculates the mean of the durations" do
47
+ 2.times { @tm.start ; sleep 0.05 ; @tm.stop }
48
+ @tm.mean.should be_close( 0.05, 0.01 )
49
+ end
50
+
51
+ it "calculates the rate of the counts " do
52
+ 5.times { @tm.start ; sleep 0.05 ; @tm.stop }
53
+ @tm.rate.should be_close( 20.00, 0.1 )
54
+ end
55
+
56
+
57
+ it "calculates the stddev of the durations" do
58
+ 3.times { |x| @tm.start ; sleep (0.05 * x) ; @tm.stop }
59
+ @tm.stddev.should be_close( 0.05, 0.001)
60
+ end
61
+
62
+ it "returns 0.0 for stddev if there is no data" do
63
+ @tm.stddev.should == 0.0
64
+ end
65
+
66
+ it "keeps track of the min value" do
67
+ 2.times { @tm.start ; sleep 0.05 ; @tm.stop }
68
+ @tm.min.should be_close( 0.05, 0.002 )
69
+ end
70
+
71
+ it "keeps track of the max value" do
72
+ 2.times { @tm.start ; sleep 0.05 ; @tm.stop }
73
+ @tm.max.should be_close( 0.05, 0.002 )
74
+ end
75
+
76
+ it "keeps track of the sum value" do
77
+ 2.times { @tm.start ; sleep 0.05 ; @tm.stop }
78
+ @tm.sum.should be_close( 0.10, 0.002 )
79
+ end
80
+
81
+ it "keeps track of the sum of squars value" do
82
+ 3.times { @tm.start ; sleep 0.05 ; @tm.stop }
83
+ @tm.sumsq.should be_close( 0.0075, 0.0001 )
84
+ end
85
+
86
+ it "keeps track of the minimum start time of all the intervals" do
87
+ f1 = Time.now.gmtime.to_f * 1000000
88
+ 5.times { @tm.start ; sleep 0.05 ; @tm.stop }
89
+ f2 = Time.now.gmtime.to_f * 1000000
90
+ @tm.sampling_start_time.should > f1
91
+ @tm.sampling_start_time.should < f2
92
+ # distance from now to start time should be greater than the distance from
93
+ # the start to the min start_time
94
+ (f2 - @tm.sampling_start_time).should > ( @tm.sampling_start_time - f1 )
95
+ end
96
+
97
+ it "keeps track of the last stop time of all the intervals" do
98
+ f1 = Time.now.gmtime.to_f * 1_000_000
99
+ 5.times { @tm.start ; sleep 0.05 ; @tm.stop }
100
+ f2 = Time.now.gmtime.to_f * 1_000_000
101
+ @tm.sampling_stop_time.should > f1
102
+ @tm.sampling_stop_time.should < f2
103
+ # distance from now to max stop time time should be less than the distance
104
+ # from the start to the max stop time
105
+ (f2 - @tm.sampling_stop_time).should < ( @tm.sampling_stop_time - f1 )
106
+ end
107
+
108
+ it "can create an already running timer" do
109
+ t = Hitimes::TimedMetric.now( 'already-running' )
110
+ t.should be_running
111
+ end
112
+
113
+ it "can measure a block of code from an instance" do
114
+ t = Hitimes::TimedMetric.new( 'measure a block' )
115
+ 3.times { t.measure { sleep 0.05 } }
116
+ t.duration.should be_close( 0.15, 0.001 )
117
+ t.count.should == 3
118
+ end
119
+
120
+ it "returns the value of the block when measuring" do
121
+ t = Hitimes::TimedMetric.new( 'measure a block' )
122
+ x = t.measure { sleep 0.05; 42 }
123
+ t.duration.should be_close( 0.05, 0.001 )
124
+ x.should == 42
125
+ end
126
+
127
+ describe "#to_hash" do
128
+
129
+ it "has name value" do
130
+ h = @tm.to_hash
131
+ h['name'].should == "test-timed-metric"
132
+ end
133
+
134
+ it "has an empty hash for additional_data" do
135
+ h = @tm.to_hash
136
+ h['additional_data'].should == Hash.new
137
+ h['additional_data'].size.should == 0
138
+ end
139
+
140
+ it "has the right sum" do
141
+ 10.times { |x| @tm.measure { sleep 0.01*x } }
142
+ h = @tm.to_hash
143
+ h['sum'].should be_close( 0.45, 0.002 )
144
+ end
145
+
146
+ fields = ::Hitimes::Stats::STATS.dup + %w[ name additional_data sampling_start_time sampling_stop_time ]
147
+ fields.each do |f|
148
+ it "should have a value for #{f}" do
149
+ @tm.measure { sleep 0.001 }
150
+ h = @tm.to_hash
151
+ h[f].should_not be_nil
152
+ end
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,172 @@
1
+ require File.expand_path( File.join( File.dirname( __FILE__ ), "spec_helper.rb" ) )
2
+
3
+ require 'hitimes/timed_value_metric'
4
+
5
+ describe Hitimes::TimedValueMetric do
6
+ before( :each ) do
7
+ @tm = Hitimes::TimedValueMetric.new( 'test-timed-value-metric' )
8
+ end
9
+
10
+ it "knows if it is running or not" do
11
+ @tm.should_not be_running
12
+ @tm.start
13
+ @tm.should be_running
14
+ @tm.stop( 1 )
15
+ @tm.should_not be_running
16
+ end
17
+
18
+ it "#split returns the last duration and the timer is still running" do
19
+ @tm.start
20
+ d = @tm.split( 1 )
21
+ @tm.should be_running
22
+ d.should > 0
23
+ @tm.value_stats.count.should == 1
24
+ @tm.timed_stats.count.should == 1
25
+ @tm.duration.should == d
26
+ end
27
+
28
+ it "#stop returns false if called more than once in a row" do
29
+ @tm.start
30
+ @tm.stop( 1 ).should > 0
31
+ @tm.stop( 1 ).should == false
32
+ end
33
+
34
+ it "does not count a currently running interval as an interval in calculations" do
35
+ @tm.start
36
+ @tm.value_stats.count.should == 0
37
+ @tm.timed_stats.count.should == 0
38
+ @tm.split( 1 )
39
+ @tm.value_stats.count.should == 1
40
+ @tm.timed_stats.count.should == 1
41
+ end
42
+
43
+ it "#split called on a stopped timer does nothing" do
44
+ @tm.start
45
+ @tm.stop( 1 )
46
+ @tm.split( 1 ).should == false
47
+ end
48
+
49
+ it "calculates the mean of the durations" do
50
+ 3.times { |x| @tm.start ; sleep 0.05 ; @tm.stop(x) }
51
+ @tm.timed_stats.mean.should be_close( 0.05, 0.01 )
52
+ @tm.value_stats.mean.should == 1.00
53
+ end
54
+
55
+ it "calculates the rate of the counts " do
56
+ 5.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
57
+ @tm.rate.should be_close( 40.0, 0.2)
58
+ end
59
+
60
+
61
+ it "calculates the stddev of the durations" do
62
+ 3.times { |x| @tm.start ; sleep (0.05 * x) ; @tm.stop(x) }
63
+ @tm.timed_stats.stddev.should be_close( 0.05, 0.001)
64
+ @tm.value_stats.stddev.should == 1.0
65
+ end
66
+
67
+ it "returns 0.0 for stddev if there is no data" do
68
+ @tm.timed_stats.stddev.should == 0.0
69
+ @tm.value_stats.stddev.should == 0.0
70
+ end
71
+
72
+ it "keeps track of the min value" do
73
+ 3.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
74
+ @tm.timed_stats.min.should be_close( 0.05, 0.001 )
75
+ @tm.value_stats.min.should == 0
76
+ end
77
+
78
+ it "keeps track of the max value" do
79
+ 3.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
80
+ @tm.timed_stats.max.should be_close( 0.05, 0.001)
81
+ @tm.value_stats.max.should == 2
82
+ end
83
+
84
+ it "keeps track of the sum value" do
85
+ 3.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
86
+ @tm.timed_stats.sum.should be_close( 0.15, 0.01 )
87
+ @tm.value_stats.sum.should == 3
88
+ end
89
+
90
+ it "keeps track of the sum of squares value" do
91
+ 3.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
92
+ @tm.timed_stats.sumsq.should be_close( 0.0075, 0.0001 )
93
+ @tm.value_stats.sumsq.should == 5
94
+ end
95
+
96
+ it "keeps track of the minimum start time of all the intervals" do
97
+ f1 = Time.now.gmtime.to_f * 1000000
98
+ 5.times { @tm.start ; sleep 0.05 ; @tm.stop( 1 ) }
99
+ f2 = Time.now.gmtime.to_f * 1000000
100
+ @tm.sampling_start_time.should > f1
101
+ @tm.sampling_start_time.should < f2
102
+ # distance from now to start time should be greater than the distance from
103
+ # the start to the min start_time
104
+ (f2 - @tm.sampling_start_time).should > ( @tm.sampling_start_time - f1 )
105
+ end
106
+
107
+ it "keeps track of the last stop time of all the intervals" do
108
+ f1 = Time.now.gmtime.to_f * 1000000
109
+ 5.times { @tm.start ; sleep 0.05 ; @tm.stop( 1 ) }
110
+ f2 = Time.now.gmtime.to_f * 1000000
111
+ @tm.sampling_stop_time.should > f1
112
+ @tm.sampling_stop_time.should < f2
113
+ # distance from now to max stop time time should be less than the distance
114
+ # from the start to the max stop time
115
+ (f2 - @tm.sampling_stop_time).should < ( @tm.sampling_stop_time - f1 )
116
+ end
117
+
118
+ it "can create an already running timer" do
119
+ t = Hitimes::TimedValueMetric.now( 'already-running' )
120
+ t.should be_running
121
+ end
122
+
123
+ it "can measure a block of code from an instance" do
124
+ t = Hitimes::TimedValueMetric.new( 'measure a block' )
125
+ 3.times { t.measure( 1 ) { sleep 0.05 } }
126
+ t.duration.should be_close( 0.15, 0.001 )
127
+ t.timed_stats.count.should == 3
128
+ t.value_stats.count.should == 3
129
+ end
130
+
131
+ it "returns the value of the block when measuring" do
132
+ t = Hitimes::TimedValueMetric.new( 'measure a block' )
133
+ x = t.measure( 42 ) { sleep 0.05; 42 }
134
+ t.duration.should be_close( 0.05, 0.001 )
135
+ x.should == 42
136
+ end
137
+
138
+ describe "#to_hash" do
139
+
140
+ it "has name value" do
141
+ h = @tm.to_hash
142
+ h['name'].should == "test-timed-value-metric"
143
+ end
144
+
145
+ it "has an empty has for additional_data" do
146
+ h = @tm.to_hash
147
+ h['additional_data'].should == Hash.new
148
+ h['additional_data'].size.should == 0
149
+ end
150
+
151
+ it "has a rate" do
152
+ 5.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
153
+ h = @tm.to_hash
154
+ h['rate'].should be_close( 40.0, 0.3 )
155
+ end
156
+
157
+ it "has a unit_count" do
158
+ 5.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
159
+ h = @tm.to_hash
160
+ h['unit_count'].should == 10
161
+ end
162
+
163
+ fields = %w[ name additional_data sampling_start_time sampling_stop_time value_stats timed_stats rate unit_count ]
164
+ fields.each do |f|
165
+ it "should have a value for #{f}" do
166
+ 3.times { |x| @tm.measure(x) { sleep 0.001 } }
167
+ h = @tm.to_hash
168
+ h[f].should_not be_nil
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,110 @@
1
+ require File.expand_path( File.join( File.dirname( __FILE__ ), "spec_helper.rb" ) )
2
+
3
+ require 'hitimes/value_metric'
4
+
5
+ describe Hitimes::ValueMetric do
6
+ before( :each ) do
7
+ @metric = Hitimes::ValueMetric.new( "testing" )
8
+ 10.times { |x| @metric.measure( x ) }
9
+ end
10
+
11
+ it 'has a name' do
12
+ @metric.name.should == "testing"
13
+ end
14
+
15
+ it "has associated data from initialization" do
16
+ m = Hitimes::ValueMetric.new( "more-data", 'foo' => 'bar', 'this' => 'that' )
17
+ m.additional_data['foo'].should == 'bar'
18
+ m.additional_data['this'].should == 'that'
19
+
20
+ m = Hitimes::ValueMetric.new( "more-data", { 'foo' => 'bar', 'this' => 'that' } )
21
+ m.additional_data['foo'].should == 'bar'
22
+ m.additional_data['this'].should == 'that'
23
+ end
24
+
25
+ it "calculates the mean of the measurements" do
26
+ @metric.mean.should == 4.5
27
+ end
28
+
29
+ it "calculates the stddev of the measurements" do
30
+ @metric.stddev.should > 0.0
31
+ end
32
+
33
+ it "returns 0.0 for stddev if there is no data" do
34
+ m = Hitimes::ValueMetric.new('0-data')
35
+ m.stddev.should == 0.0
36
+ end
37
+
38
+ it "keeps track of the sum of data" do
39
+ @metric.sum.should == 45.0
40
+ end
41
+
42
+ it "keeps track of the sum of squars of data" do
43
+ @metric.sumsq.should == 285.0
44
+ end
45
+
46
+ it "retuns 0.0 for mean if there is no data" do
47
+ Hitimes::ValueMetric.new('0-data').mean.should == 0.0
48
+ end
49
+
50
+ it "keeps track of the min value" do
51
+ @metric.min.should == 0
52
+ end
53
+
54
+ it "keeps track of the max value" do
55
+ @metric.max.should == 9
56
+ end
57
+
58
+ it "keeps track of the first start time of all the measurements" do
59
+ m = Hitimes::ValueMetric.new( "first-start-time" )
60
+ f1 = Time.now.gmtime.to_f * 1_000_000
61
+ 10.times{ |x| m.measure( x ) }
62
+ f2 = Time.now.gmtime.to_f * 1_000_000
63
+ m.sampling_start_time.should > f1
64
+ m.sampling_stop_time.should < f2
65
+ # distance from now to start time should be greater than the distance from
66
+ # the start to the min start_time
67
+ (f2 - m.sampling_start_time).should > ( m.sampling_start_time - f1 )
68
+ end
69
+
70
+ it "keeps track of the last stop time of all the intervals" do
71
+ m = Hitimes::ValueMetric.new( "last-stop-time" )
72
+ f1 = Time.now.gmtime.to_f * 1_000_000
73
+ 10.times {|x| m.measure( x ) }
74
+ f2 = Time.now.gmtime.to_f * 1_000_000
75
+ m.sampling_stop_time.should > f1
76
+ m.sampling_stop_time.should < f2
77
+ # distance from now to max stop time time should be less than the distance
78
+ # from the start to the max stop time
79
+ (f2 - m.sampling_stop_time).should < ( m.sampling_stop_time - f1 )
80
+ end
81
+
82
+ describe "#to_hash" do
83
+
84
+ it "has name value" do
85
+ h = @metric.to_hash
86
+ h['name'].should == "testing"
87
+ end
88
+
89
+ it "has an empty has for additional_data" do
90
+ h = @metric.to_hash
91
+ h['additional_data'].should == Hash.new
92
+ h['additional_data'].size.should == 0
93
+ end
94
+
95
+ it "has the right sum" do
96
+ h = @metric.to_hash
97
+ h['sum'].should == 45
98
+ end
99
+
100
+ fields = ::Hitimes::Stats::STATS.dup + %w[ name additional_data sampling_start_time sampling_stop_time ]
101
+ fields = fields - [ 'rate' ]
102
+ fields.each do |f|
103
+ it "should have a value for #{f}" do
104
+ h = @metric.to_hash
105
+ h[f].should_not be_nil
106
+ end
107
+ end
108
+ end
109
+ end
110
+
@@ -0,0 +1,33 @@
1
+ require File.expand_path( File.join( File.dirname( __FILE__ ), "spec_helper" ) )
2
+
3
+ describe "Hitimes::Version" do
4
+ it "should have a major numbers that is >= 0" do
5
+ Hitimes::Version::MAJOR.should >= 0
6
+ end
7
+
8
+ it "should have a minor number that is >= 0" do
9
+ Hitimes::Version::MINOR.should >= 0
10
+ end
11
+
12
+ it "should have a tiny number that is >= 0" do
13
+ Hitimes::Version::BUILD.should >= 0
14
+ end
15
+
16
+ it "should have an array representation" do
17
+ Hitimes::Version.to_a.should have(3).items
18
+ end
19
+
20
+ it "should have a string representation" do
21
+ Hitimes::Version.to_s.should match(/\d+\.\d+\.\d+/)
22
+ end
23
+
24
+ it "should have a hash representation" do
25
+ [ :major, :minor, :build ].each do |k|
26
+ Hitimes::Version.to_hash[k].should_not be_nil
27
+ end
28
+ end
29
+
30
+ it "should be accessable as a constant" do
31
+ Hitimes::VERSION.should match(/\d+\.\d+\.\d+/)
32
+ end
33
+ end