hitimes 1.0.4-x86-mswin32

Sign up to get free protection for your applications and to get access to all the features.
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