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,8 @@
1
+ #--
2
+ # Copyright (c) 2008 Jeremy Hinegardner
3
+ # All rights reserved. See LICENSE and/or COPYING for details
4
+ #++
5
+
6
+ module Hitimes
7
+ VERSION = "1.3.0"
8
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hitimes do
4
+ it "can time a block of code" do
5
+ d = Hitimes.measure do
6
+ sleep 0.2
7
+ end
8
+ d.must_be_close_to(0.2, 0.002)
9
+ end
10
+
11
+ it "raises an error if measure is called with no block" do
12
+ lambda{ Hitimes.measure }.must_raise( Hitimes::Error )
13
+ end
14
+
15
+ it "has the raw instant value" do
16
+ v = Hitimes.raw_instant
17
+ v.must_be :>, 0
18
+ end
19
+
20
+ it "has access to the instant conversion factor" do
21
+ f = Hitimes::INSTANT_CONVERSION_FACTOR
22
+ f.must_be :>, 0
23
+ end
24
+ end
@@ -0,0 +1,136 @@
1
+ require "spec_helper"
2
+
3
+ describe Hitimes::Interval do
4
+ it "raises an error if duration is called on a non-started interval" do
5
+ i = Hitimes::Interval.new
6
+ lambda{ i.duration }.must_raise( Hitimes::Error, /\AAttempt to report a duration on an interval that has not started\Z/ )
7
+ end
8
+
9
+ it "raises an error if stop is called on a non-started interval" do
10
+ i = Hitimes::Interval.new
11
+ lambda { i.stop }.must_raise( Hitimes::Error, /\AAttempt to stop an interval that has not started\Z/ )
12
+ end
13
+
14
+ it "knows if it has been started" do
15
+ i = Hitimes::Interval.new
16
+ i.started?.must_equal false
17
+
18
+ i.start
19
+ i.started?.must_equal true
20
+ end
21
+
22
+ it "knows if it has been stopped" do
23
+ i = Hitimes::Interval.new
24
+ i.start
25
+ i.stopped?.must_equal false
26
+ i.stop
27
+ i.stopped?.must_equal true
28
+ end
29
+
30
+ it "knows if it is currently running" do
31
+ i = Hitimes::Interval.new
32
+ i.running?.must_equal false
33
+ i.start
34
+ i.running?.must_equal true
35
+ i.stop
36
+ i.running?.must_equal false
37
+ end
38
+
39
+ it "can time a block of code" do
40
+ d = Hitimes::Interval.measure do
41
+ sleep 0.2
42
+ end
43
+ d.must_be_close_to(0.2, 0.002)
44
+ end
45
+
46
+ it "raises an error if measure is called with no block" do
47
+ lambda{ Hitimes::Interval.measure }.must_raise( Hitimes::Error, /\ANo block given to Interval.measure\Z/ )
48
+ end
49
+
50
+ it "creates an interval via #now" do
51
+ i = Hitimes::Interval.now
52
+ i.started?.must_equal true
53
+ i.stopped?.must_equal false
54
+ end
55
+
56
+ it "calling duration multiple times returns successivly grater durations" do
57
+ i = Hitimes::Interval.new
58
+ i.start
59
+ y = i.duration
60
+ z = i.duration
61
+ z.must_be :>, y
62
+ end
63
+
64
+ it "calling start multiple times on has no effect after the first call" do
65
+ i = Hitimes::Interval.new
66
+ i.start.must_equal true
67
+ x = i.start_instant
68
+ i.start_instant.must_be :>, 0
69
+ i.start.must_equal false
70
+ x.must_equal i.start_instant
71
+ end
72
+
73
+ it "returns the duration on the first call to stop" do
74
+ i = Hitimes::Interval.now
75
+ d = i.stop
76
+ d.must_be_instance_of( Float )
77
+ end
78
+
79
+ it "calling stop multiple times on has no effect after the first call" do
80
+ i = Hitimes::Interval.new
81
+ i.start.must_equal true
82
+ i.stop
83
+
84
+ x = i.stop_instant
85
+ i.stop_instant.must_be :>, 0
86
+ i.stop.must_equal false
87
+ x.must_equal i.stop_instant
88
+
89
+ end
90
+
91
+ it "duration does not change after stop is calledd" do
92
+ i = Hitimes::Interval.new
93
+ i.start
94
+ x = i.stop
95
+ y = i.duration
96
+ i.stop.must_equal false
97
+
98
+ z = i.duration
99
+
100
+ x.must_equal y
101
+ x.must_equal z
102
+
103
+ y.must_equal z
104
+ end
105
+
106
+ it "can return how much time has elapsed from the start without stopping the interval" do
107
+ i = Hitimes::Interval.new
108
+ i.start
109
+ x = i.duration_so_far
110
+ i.running?.must_equal true
111
+ y = i.duration_so_far
112
+ i.stop
113
+ x.must_be :<, y
114
+ x.must_be :<, i.duration
115
+ y.must_be :<, i.duration
116
+ end
117
+
118
+ describe "#split" do
119
+
120
+ it "creates a new Interval object" do
121
+ i = Hitimes::Interval.new
122
+ i.start
123
+ i2 = i.split
124
+ i.object_id.wont_equal i2.object_id
125
+ end
126
+
127
+ it "with the stop instant equivialent to the previous Interval's start instant" do
128
+ i = Hitimes::Interval.new
129
+ i.start
130
+ i2 = i.split
131
+ i.stop_instant.must_equal i2.start_instant
132
+ end
133
+ end
134
+
135
+ end
136
+
@@ -0,0 +1,28 @@
1
+ require "spec_helper"
2
+
3
+ describe Hitimes::Metric do
4
+ before( :each ) do
5
+ @metric = Hitimes::Metric.new( "testing" )
6
+ end
7
+
8
+ it 'has a name' do
9
+ @metric.name.must_equal "testing"
10
+ end
11
+
12
+ it "has associated data from initialization" do
13
+ m = Hitimes::Metric.new( "more-data", 'foo' => 'bar', 'this' => 'that' )
14
+ m.additional_data['foo'].must_equal 'bar'
15
+ m.additional_data['this'].must_equal 'that'
16
+
17
+ m = Hitimes::Metric.new( "more-data", { 'foo' => 'bar', 'this' => 'that' } )
18
+ m.additional_data['foo'].must_equal 'bar'
19
+ m.additional_data['this'].must_equal 'that'
20
+ end
21
+
22
+ it "initially has no sampling times" do
23
+ @metric.sampling_start_time.must_be_nil
24
+ @metric.sampling_stop_time.must_be_nil
25
+ end
26
+ end
27
+
28
+
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hitimes::MutexedStats do
4
+ before( :each ) do
5
+ @threads = 5
6
+ @iters = 10_000
7
+ @final_value = @threads * @iters
8
+ end
9
+
10
+ def run_with_scissors( stats, threads, iters )
11
+ spool = []
12
+ threads.times do |t|
13
+ spool << Thread.new { iters.times{ stats.update( 1 ) } }
14
+ end
15
+ spool.each { |t| t.join }
16
+ return stats
17
+ end
18
+
19
+ if (not defined? RUBY_ENGINE) or (RUBY_ENGINE == "ruby") then
20
+ it "Hitimes::Stats is threadsafe" do
21
+ stats = run_with_scissors( ::Hitimes::Stats.new, @threads, @iters )
22
+ stats.count.must_equal @final_value
23
+ end
24
+ else
25
+ it "Hitimes::Stats is not threadsafe" do
26
+ stats = run_with_scissors( ::Hitimes::Stats.new, @threads, @iters )
27
+ stats.count.wont_equal @final_value
28
+ end
29
+ end
30
+
31
+ it "has a threadsafe update" do
32
+ stats = run_with_scissors( ::Hitimes::MutexedStats.new, @threads, @iters )
33
+ stats.count.must_equal @final_value
34
+ end
35
+
36
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hitimes::Paths do
4
+ it "can access the root dir of the project" do
5
+ Hitimes::Paths.root_dir.must_equal File.expand_path( File.join( File.dirname( __FILE__ ), ".." ) ) + ::File::SEPARATOR
6
+ end
7
+
8
+ it "can access the lib path of the project" do
9
+ Hitimes::Paths.lib_path.must_equal File.expand_path( File.join( File.dirname( __FILE__ ), "..", "lib" ) ) + ::File::SEPARATOR
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ if RUBY_VERSION >= '1.9.2' then
2
+ require 'simplecov'
3
+ puts "Using coverage!"
4
+ SimpleCov.start if ENV['COVERAGE']
5
+ end
6
+
7
+ gem 'minitest'
8
+ require 'hitimes'
9
+ require 'minitest/autorun'
10
+ require 'minitest/pride'
11
+
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+ require 'json'
3
+
4
+ describe Hitimes::Stats do
5
+ before( :each ) do
6
+ @stats = Hitimes::Stats.new
7
+ @full_stats = Hitimes::Stats.new
8
+
9
+ [ 1, 2, 3].each { |i| @full_stats.update( i ) }
10
+ end
11
+
12
+ it "is initialized with 0 values" do
13
+ @stats.count.must_equal 0
14
+ @stats.min.must_equal 0.0
15
+ @stats.max.must_equal 0.0
16
+ @stats.sum.must_equal 0.0
17
+ @stats.rate.must_equal 0.0
18
+ end
19
+
20
+ it "calculates the mean correctly" do
21
+ @full_stats.mean.must_equal 2.0
22
+ end
23
+
24
+ it "calculates the rate correctly" do
25
+ @full_stats.rate.must_equal 0.5
26
+ end
27
+
28
+ it "tracks the maximum value" do
29
+ @full_stats.max.must_equal 3.0
30
+ end
31
+
32
+ it "tracks the minimum value" do
33
+ @full_stats.min.must_equal 1.0
34
+ end
35
+
36
+ it "tracks the count" do
37
+ @full_stats.count.must_equal 3
38
+ end
39
+
40
+ it "tracks the sum" do
41
+ @full_stats.sum.must_equal 6.0
42
+ end
43
+
44
+ it "calculates the standard deviation" do
45
+ @full_stats.stddev.must_equal 1.0
46
+ end
47
+
48
+ it "calculates the sum of squares " do
49
+ @full_stats.sumsq.must_equal 14.0
50
+ end
51
+
52
+ describe "#to_hash " do
53
+ it "converts to a Hash" do
54
+ h = @full_stats.to_hash
55
+ h.size.must_equal ::Hitimes::Stats::STATS.size
56
+ h.keys.sort.must_equal ::Hitimes::Stats::STATS
57
+ end
58
+
59
+ it "converts to a limited Hash if given arguments" do
60
+ h = @full_stats.to_hash( "min", "max", "mean" )
61
+ h.size.must_equal 3
62
+ h.keys.sort.must_equal %w[ max mean min ]
63
+
64
+ h = @full_stats.to_hash( %w[ count rate ] )
65
+ h.size.must_equal 2
66
+ h.keys.sort.must_equal %w[ count rate ]
67
+ end
68
+
69
+ it "raises NoMethodError if an invalid stat is used" do
70
+ lambda { @full_stats.to_hash( "wibble" ) }.must_raise( NoMethodError )
71
+ end
72
+ end
73
+
74
+ describe "#to_json" do
75
+ it "converts to a json string" do
76
+ j = @full_stats.to_json
77
+ h = JSON.parse( j )
78
+ h.size.must_equal ::Hitimes::Stats::STATS.size
79
+ h.keys.sort.must_equal ::Hitimes::Stats::STATS
80
+ end
81
+
82
+ it "converts to a limited Hash if given arguments" do
83
+ j = @full_stats.to_json( "min", "max", "mean" )
84
+ h = JSON.parse( j )
85
+ h.size.must_equal 3
86
+ h.keys.sort.must_equal %w[ max mean min ]
87
+
88
+ j = @full_stats.to_json( %w[ count rate ] )
89
+ h = JSON.parse( j )
90
+ h.size.must_equal 2
91
+ h.keys.sort.must_equal %w[ count rate ]
92
+ end
93
+
94
+ it "raises NoMethodError if an invalid stat is used" do
95
+ lambda { @full_stats.to_json( "wibble" ) }.must_raise( NoMethodError )
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,155 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hitimes::TimedMetric do
4
+ before( :each ) do
5
+ @tm = Hitimes::TimedMetric.new( 'test-timed-metric' )
6
+ end
7
+
8
+ it "knows if it is running or not" do
9
+ @tm.running?.must_equal false
10
+ @tm.start
11
+ @tm.running?.must_equal true
12
+ @tm.stop
13
+ @tm.running?.must_equal false
14
+ end
15
+
16
+ it "#split returns the last duration and the timer is still running" do
17
+ @tm.start
18
+ d = @tm.split
19
+ @tm.running?.must_equal true
20
+ d.must_be :>, 0
21
+ @tm.count.must_equal 1
22
+ @tm.duration.must_equal d
23
+ end
24
+
25
+ it "#stop returns false if called more than once in a row" do
26
+ @tm.start
27
+ @tm.stop.must_be :>, 0
28
+ @tm.stop.must_equal false
29
+ end
30
+
31
+ it "does not count a currently running interval as an interval in calculations" do
32
+ @tm.start
33
+ @tm.count.must_equal 0
34
+ @tm.split
35
+ @tm.count.must_equal 1
36
+ end
37
+
38
+ it "#split called on a stopped timer does nothing" do
39
+ @tm.start
40
+ @tm.stop
41
+ @tm.split.must_equal false
42
+ end
43
+
44
+ it "calculates the mean of the durations" do
45
+ 2.times { @tm.start ; sleep 0.05 ; @tm.stop }
46
+ @tm.mean.must_be_close_to(0.05, 0.002)
47
+ end
48
+
49
+ it "calculates the rate of the counts " do
50
+ 5.times { @tm.start ; sleep 0.05 ; @tm.stop }
51
+ @tm.rate.must_be_close_to(20.00, 0.5)
52
+ end
53
+
54
+
55
+ it "calculates the stddev of the durations" do
56
+ 3.times { |x| @tm.start ; sleep(0.05 * x) ; @tm.stop }
57
+ @tm.stddev.must_be_close_to(0.05)
58
+ end
59
+
60
+ it "returns 0.0 for stddev if there is no data" do
61
+ @tm.stddev.must_equal 0.0
62
+ end
63
+
64
+ it "keeps track of the min value" do
65
+ 2.times { @tm.start ; sleep 0.05 ; @tm.stop }
66
+ @tm.min.must_be_close_to(0.05, 0.01)
67
+ end
68
+
69
+ it "keeps track of the max value" do
70
+ 2.times { @tm.start ; sleep 0.05 ; @tm.stop }
71
+ @tm.max.must_be_close_to(0.05, 0.01)
72
+ end
73
+
74
+ it "keeps track of the sum value" do
75
+ 2.times { @tm.start ; sleep 0.05 ; @tm.stop }
76
+ @tm.sum.must_be_close_to(0.10, 0.01)
77
+ end
78
+
79
+ it "keeps track of the sum of squars value" do
80
+ 3.times { @tm.start ; sleep 0.05 ; @tm.stop }
81
+ @tm.sumsq.must_be_close_to(0.0075)
82
+ end
83
+
84
+ it "keeps track of the minimum start time of all the intervals" do
85
+ f1 = Time.now.gmtime.to_f * 1_000_000
86
+ 5.times { @tm.start ; sleep 0.05 ; @tm.stop }
87
+ f2 = Time.now.gmtime.to_f * 1_000_000
88
+ @tm.sampling_start_time.must_be :>=, f1
89
+ @tm.sampling_start_time.must_be :<, f2
90
+ # distance from now to start time should be greater than the distance from
91
+ # the start to the min start_time
92
+ (f2 - @tm.sampling_start_time).must_be :>, ( @tm.sampling_start_time - f1 )
93
+ end
94
+
95
+ it "keeps track of the last stop time of all the intervals" do
96
+ f1 = Time.now.gmtime.to_f * 1_000_000
97
+ sleep 0.01
98
+ 5.times { @tm.start ; sleep 0.05 ; @tm.stop }
99
+ sleep 0.01
100
+ f2 = Time.now.gmtime.to_f * 1_000_000
101
+ @tm.sampling_stop_time.must_be :>, f1
102
+ @tm.sampling_stop_time.must_be :<=, 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).must_be :<, ( @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.running?.must_equal true
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.must_be_close_to(0.15, 0.01)
117
+ t.count.must_equal 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.must_be_close_to(0.05, 0.002)
124
+ x.must_equal 42
125
+ end
126
+
127
+ describe "#to_hash" do
128
+
129
+ it "has name value" do
130
+ h = @tm.to_hash
131
+ h['name'].must_equal "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'].must_equal Hash.new
137
+ h['additional_data'].size.must_equal 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'].must_be_close_to(0.45, 0.01)
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 "has a value for #{f}" do
149
+ @tm.measure { sleep 0.001 }
150
+ h = @tm.to_hash
151
+ h[f].wont_be_nil
152
+ end
153
+ end
154
+ end
155
+ end