hitimes 1.3.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e479c2fbfddbd9d35a7f9bcc4580b265f43cd9fa46a7a986e1d10401c58b882
4
- data.tar.gz: 5751466c5f9a518a607b4f14df5e368dd85d990fccbc665f6d080b5435982b4d
3
+ metadata.gz: dbcf72d52334876051ff59dbc24a84f2a2be8dbde31979d858819db54eba8f7f
4
+ data.tar.gz: c19e0e771b17465b6f57a5e229d11e76b132c1d3c170ff3da1428eeb11cac40a
5
5
  SHA512:
6
- metadata.gz: fabe96db83fec72aac45648908229119bce50fdef39e61fc00f426a7d44ba3da791be416b5e44f0c6bd4cae822e241e152f827c490fb46658946a910ffad6579
7
- data.tar.gz: e1ba6e894dbabf0911df83bbae59a9dfd201b2edfd605a2fe9c27f46e2d5d5bf80105918f3a718df02de0fccf975cc36ada85254b53f949ce78036fe9130d050
6
+ metadata.gz: e1005099d605876d72c5d7147007b051f77b1451c83a9eac420807ed221f1e484098dc276d9d2cbc2c1f74dca19ec032334bdd6e81ab3c9304e5991ba8e7ccb9
7
+ data.tar.gz: e7b74b1d122348097900175b8e9a422b1cc49782994c82a55e1017f9742de08cadaae70b8ea8b9603f2bc05e0e471278321a0ee76fef06997abde5c6d05561d3
@@ -33,17 +33,6 @@ easiest way to contribute.
33
33
  * Add yourself to the contributors section below.
34
34
  * Submit your [pull request][].
35
35
 
36
- ## Building Windows Binaries
37
-
38
- This is done using https://github.com/rake-compiler/rake-compiler-dock
39
-
40
- 1. have VirtualBox installed
41
- 2. have Docker Machine installed (https://docs.docker.com/engine/installation/)
42
- 3. `gem install rake-compiler-dock`
43
- 4. `rake-compiler-dock` (this could take a while)
44
- 5. `bundle`
45
- 6. `rake cross native gem`
46
-
47
36
  # Contributors
48
37
 
49
38
  * Jeremy Hinegardner
data/HISTORY.md CHANGED
@@ -1,4 +1,11 @@
1
- # Hitimes Changelog
1
+ # Hitimes Changeloga
2
+ ## Version 2.0.0 2019-09-23
3
+
4
+ * Remove the C and Java extensions as `Process.clock_gettime()` has the same
5
+ resolution as what the extensions did.
6
+ * Update all depedencies and resolve deprecations
7
+ * Now usable on truffleruby
8
+
2
9
  ## Version 1.3.1 2019-01-18
3
10
 
4
11
  * Update jruby extension to not use global runtime state (thanks @kares) (#70)
@@ -6,20 +6,10 @@ README.md
6
6
  Rakefile
7
7
  examples/benchmarks.rb
8
8
  examples/stats.rb
9
- ext/hitimes/c/extconf.rb
10
- ext/hitimes/c/hitimes.c
11
- ext/hitimes/c/hitimes_instant_clock_gettime.c
12
- ext/hitimes/c/hitimes_instant_osx.c
13
- ext/hitimes/c/hitimes_instant_windows.c
14
- ext/hitimes/c/hitimes_interval.c
15
- ext/hitimes/c/hitimes_interval.h
16
- ext/hitimes/c/hitimes_stats.c
17
- ext/hitimes/c/hitimes_stats.h
18
- ext/hitimes/java/src/hitimes/Hitimes.java
19
- ext/hitimes/java/src/hitimes/HitimesInterval.java
20
- ext/hitimes/java/src/hitimes/HitimesService.java
21
- ext/hitimes/java/src/hitimes/HitimesStats.java
22
9
  lib/hitimes.rb
10
+ lib/hitimes/initialize.rb
11
+ lib/hitimes/instant.rb
12
+ lib/hitimes/interval.rb
23
13
  lib/hitimes/metric.rb
24
14
  lib/hitimes/mutexed_stats.rb
25
15
  lib/hitimes/paths.rb
@@ -40,5 +30,4 @@ spec/timed_value_metric_spec.rb
40
30
  spec/value_metric_spec.rb
41
31
  spec/version_spec.rb
42
32
  tasks/default.rake
43
- tasks/extension.rake
44
33
  tasks/this.rb
data/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  A fast, high resolution timer library for recording peformance metrics.
8
8
 
9
9
  * [Homepage](http://github.com/copiousfreetime/hitimes)
10
- * [Github project](http://github.com.org/copiousfreetime/hitimes)
10
+ * [Github project](http://github.com/copiousfreetime/hitimes)
11
11
  * email jeremy at copiousfreetime dot org
12
12
  * `git clone url git://github.com/copiousfreetime/hitimes.git`
13
13
 
@@ -143,16 +143,9 @@ puts timed_value_metric.value_stats.stddev
143
143
 
144
144
  ### Implementation details
145
145
 
146
- Hitimes use the appropriate low-level system call for each operating system to
146
+ Hitimes uses the internal ruby `Process::clock_gettime()` to
147
147
  get the highest granularity time increment possible. Generally this is
148
- nanosecond resolution, or whatever the hardware chip in the CPU supports.
149
-
150
- It currently supports any of the following systems:
151
-
152
- * any system with the POSIX call `clock_gettime()`
153
- * Mac OS X
154
- * Windows
155
- * JRuby
148
+ nanosecond resolution, or whatever the hardware in the CPU supports.
156
149
 
157
150
  ## Support
158
151
 
@@ -164,15 +157,12 @@ The current officially supported versions of Ruby are:
164
157
  * MRI Ruby (all platforms) 2.3 - 2.6
165
158
  * JRuby 9.1.17.0, 9.2.X.X
166
159
 
167
- Unofficially supported versions, these have been supported in the past when they
168
- were the primary rubies around. In all likelihood they still work, but are not
169
- supported.
160
+ Unofficially supported versions, any version of MRI from Ruby 2.1 and up. Sincd
161
+ the C Extension has been removed Hitimes should work with any ruby that is 2.1
162
+ or greater as that is when `Process.clock_gettime()` was implemented.
170
163
 
171
- * MRI Ruby (linux/mac/bsd/unix/etc) - everything from 1.8.7 to 2.2
172
- * MRI Ruby (windows) - 2.0 and up
173
- * Ruby 1.8 and 1.9 for windows are supported in hitimes version 1.2.4 or earlier
174
- * JRuby - I think everything back to 1.4
175
- * Rubinius
164
+ For versions of Ruby before 2.1 please use Hitimes 1.3, the extension code is
165
+ still in there and they should still work.
176
166
 
177
167
  ## Contributing
178
168
 
data/Rakefile CHANGED
@@ -7,22 +7,13 @@ This.email = "jeremy@copiousfreetime.org"
7
7
  This.homepage = "http://github.com/copiousfreetime/#{ This.name }"
8
8
 
9
9
  This.ruby_gemspec do |spec|
10
- spec.add_development_dependency( 'rake' , '~> 12.0')
10
+ spec.add_development_dependency( 'rake' , '~> 12.3')
11
11
  spec.add_development_dependency( 'minitest' , '~> 5.5' )
12
- spec.add_development_dependency( 'rdoc' , '~> 5.0' )
13
- spec.add_development_dependency( 'json' , '~> 2.0' )
14
- spec.add_development_dependency( 'rake-compiler', '~> 1.0' )
15
- spec.add_development_dependency( 'rake-compiler-dock', '~> 0.6' )
16
- spec.add_development_dependency( 'simplecov' , '~> 0.14' )
12
+ spec.add_development_dependency( 'rdoc' , '~> 6.2' )
13
+ spec.add_development_dependency( 'json' , '~> 2.2' )
14
+ spec.add_development_dependency( 'simplecov' , '~> 0.17' )
17
15
 
18
- spec.extensions.concat This.extension_conf_files
19
16
  spec.license = "ISC"
20
17
  end
21
18
 
22
- This.java_gemspec( This.ruby_gemspec ) do |spec|
23
- spec.extensions.clear
24
- spec.files << "lib/hitimes/hitimes.jar"
25
- end
26
-
27
19
  load 'tasks/default.rake'
28
- load 'tasks/extension.rake'
@@ -25,36 +25,8 @@ module Hitimes
25
25
  end
26
26
  require 'hitimes/paths'
27
27
  require 'hitimes/version'
28
-
29
- # Load the binary extension, try loading one for the specific version of ruby
30
- # and if that fails, then fall back to one in the top of the library.
31
- # this is the method recommended by rake-compiler
32
-
33
- attempts = [
34
- "hitimes/#{RUBY_VERSION.sub(/\.\d+$/,'')}/hitimes",
35
- "hitimes/hitimes"
36
- ]
37
- loaded = false
38
-
39
- path_exceptions = []
40
- attempts.each do |path|
41
- begin
42
- require path
43
- loaded = true
44
- break
45
- rescue LoadError => load_error
46
- full_path = File.expand_path(path)
47
- path_exceptions << [ full_path, load_error.message ]
48
- end
49
- end
50
-
51
- if !loaded then
52
- msg = ["Unable to find binary extension, was hitimes installed correctly? The following paths were tried."]
53
- path_exceptions.each do |path, message|
54
- msg << "#{path} : #{message}"
55
- end
56
- raise LoadError, msg.join("\n")
57
- end
28
+ require 'hitimes/instant'
29
+ require 'hitimes/interval'
58
30
 
59
31
  require 'hitimes/stats'
60
32
  require 'hitimes/mutexed_stats'
@@ -0,0 +1,65 @@
1
+ module Hitimes
2
+
3
+ # Internal: Internal setup that is done when the library is loaded
4
+ #
5
+ # We want to determine what clock to use for this machine. So we need to
6
+ # intropect the ruby environment and then setup some initial constants. These
7
+ # methods are used in lib/hitimes/instant.rb to help setup the CLOCK_ID
8
+ # constant
9
+ #
10
+ module Initialize
11
+
12
+ # Internal: Return the list of clock ids, in general priority order,
13
+ # assuming they all have the same resolution.
14
+ #
15
+ # On OSX we probably want to use the MACH time first, and then fall back to
16
+ # CLOCK_... Constants on other machines.
17
+ #
18
+ # The one requirement is that they are monotonically increasing clocks
19
+ #
20
+ # Returns an array of clock ids
21
+ def potential_clock_ids
22
+ Array.new.tap do |clock_ids|
23
+
24
+ # if we're on OSX this will add in an additional clock_id, although not
25
+ # sure why it is just a symbol and not a Process:: constant
26
+ #
27
+ begin
28
+ Process.clock_getres(:MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC)
29
+ clock_ids << :MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC
30
+ rescue Errno::EINVAL
31
+ # not on OSX
32
+ end
33
+
34
+ # General monotonic constants in general order of priority assuming they
35
+ # all have the same resolution
36
+ #
37
+ %i[ CLOCK_MONOTONIC_RAW CLOCK_BOOTTIME CLOCK_MONOTONIC_PRECISE CLOCK_MONOTONIC ].each do |c|
38
+ clock_ids << Process.const_get(c) if Process.const_defined?(c)
39
+ end
40
+
41
+ end
42
+ end
43
+ module_function :potential_clock_ids
44
+
45
+ # Internal: Determine what clock to use for the machine we are one. We want
46
+ # the highest resolution clock possible, which should be nanosecond
47
+ # resolution.
48
+ #
49
+ # Get the resolution of each clock id and then return the higest resolution
50
+ # id from the list
51
+ #
52
+ # Returns the clock id to use on this ruby
53
+ def determine_clock_id
54
+ ids_and_resolutions = potential_clock_ids.map { |clock_id|
55
+ [clock_id, Process.clock_getres(clock_id)]
56
+ }
57
+
58
+ # Sort them by the resolution - we want the smallest one first
59
+ ids_and_resolutions.sort_by! { |pair| pair[1] }
60
+
61
+ return ids_and_resolutions.first[0]
62
+ end
63
+ module_function :determine_clock_id
64
+ end
65
+ end
@@ -0,0 +1,65 @@
1
+ require 'hitimes/initialize'
2
+
3
+ module Hitimes
4
+ # Public: The clock_id to use in Process.clock_gettime
5
+ CLOCK_ID = Initialize.determine_clock_id.freeze
6
+
7
+ # Public: The resolution of the clock
8
+ CLOCK_RESOLUTION_NANOSECONDS = Process.clock_getres(CLOCK_ID, :nanosecond).freeze
9
+
10
+ # Internal: The fraction of second of a nanosecond
11
+ NANOSECONDS_PER_SECOND = 1e9
12
+
13
+ # Public: The smallest fraction of a second hitimes can do
14
+ CLOCK_RESOLUTION_SECONDS = CLOCK_RESOLUTION_NANOSECONDS / NANOSECONDS_PER_SECOND
15
+
16
+ # Public: The factor used to convert the instant values to fractional seconds
17
+ #
18
+ # The raw instant values are divided by this value to get float seconds
19
+ INSTANT_CONVERSION_FACTOR = CLOCK_RESOLUTION_NANOSECONDS * NANOSECONDS_PER_SECOND
20
+
21
+
22
+ # Public: Get the raw instant
23
+ #
24
+ # Examples:
25
+ #
26
+ # Hitimes.raw_instant
27
+ #
28
+ # Returns the raw instant value
29
+ def raw_instant
30
+ Process.clock_gettime(::Hitimes::CLOCK_ID, :nanosecond)
31
+ end
32
+ module_function :raw_instant
33
+
34
+ # Internal: The human readable clock name of the CLOCK_ID as a string
35
+ #
36
+ # Returns the clock name as a String
37
+ def clock_name
38
+ case CLOCK_ID
39
+ when Symbol
40
+ CLOCK_ID.to_s
41
+ else
42
+ const = Process.constants.grep(/CLOCK/).find { |c|
43
+ CLOCK_ID == Process.const_get(c)
44
+ }
45
+ "Process::#{const.to_s}"
46
+ end
47
+ end
48
+ module_function :clock_name
49
+
50
+ # Internal: The human readable clock resolution
51
+ #
52
+ # Returns the clock resolution as a string
53
+ def clock_resolution_description
54
+ "#{CLOCK_RESOLUTION_NANOSECONDS}ns"
55
+ end
56
+ module_function :clock_resolution_description
57
+
58
+ # Internal: The human readable clock description that is used by hitimes
59
+ #
60
+ # Returns the clock description as a String
61
+ def clock_description
62
+ "#{clock_name} #{clock_resolution_description}"
63
+ end
64
+ module_function :clock_description
65
+ end
@@ -0,0 +1,171 @@
1
+ # Copyright (c) 2008 Jeremy Hinegardner
2
+ # All rights reserved. See LICENSE and/or COPYING for details.
3
+ #
4
+ module Hitimes
5
+ # This is the lowest level timing mechanism available. It allows for easy
6
+ # measuring based upon a block:
7
+ #
8
+ # duration = Interval.measure { ... }
9
+ #
10
+ # Or measuring something specifically
11
+ #
12
+ # interval = Interval.new
13
+ # interval.start
14
+ # duration = interval.stop
15
+ #
16
+ # Allocating and starting an interval can be done in one method call with
17
+ #
18
+ # interval = Interval.now
19
+ #
20
+ # Interval is useful when you only need to track a single interval of time, or
21
+ # if you do not want to track statistics about an operation.
22
+ class Interval
23
+
24
+ # Public: The integer representing the start instant of the Interval. This
25
+ # valuea is not useful on its own. It is a platform dependent value.
26
+ attr_reader :start_instant
27
+
28
+ # Public: The integer representing the stop instant of the Interval. This
29
+ # value is not useful on its own. It is a platform dependent value.
30
+ attr_reader :stop_instant
31
+
32
+ def initialize(start = nil, stop = nil)
33
+ @start_instant = start
34
+ @stop_instant = stop
35
+ @duration = -Float::INFINITY
36
+ end
37
+
38
+ # call-seq:
39
+ # Interval.now -> Interval
40
+ #
41
+ # Create an interval that has already started
42
+ #
43
+ def self.now
44
+ Interval.new(Hitimes.raw_instant)
45
+ end
46
+
47
+ # call-seq:
48
+ # Interval.measure { } -> Float
49
+ #
50
+ # Times the execution of the block returning the number of seconds it took
51
+ def self.measure(&block)
52
+ raise Error, "No block given to Interval.measure" unless block_given?
53
+
54
+ i = Interval.now
55
+ yield
56
+ i.stop
57
+
58
+ return i.duration
59
+ end
60
+
61
+ # call-seq:
62
+ # interval.split -> Interval
63
+ #
64
+ # Immediately stop the current interval and start a new interval that has a
65
+ # start_instant equivalent to the stop_interval of self.
66
+ def split
67
+ @stop_instant = ::Hitimes.raw_instant
68
+ return Interval.new(@stop_instant)
69
+ end
70
+
71
+ # call-seq:
72
+ # interval.start -> boolean
73
+ #
74
+ # mark the start of the interval. Calling start on an already started
75
+ # interval has no effect. An interval can only be started once. If the
76
+ # interval is truely started +true+ is returned otherwise +false+.
77
+ def start
78
+ return false if started?
79
+ @start_instant = ::Hitimes.raw_instant
80
+ true
81
+ end
82
+
83
+ # call-seq:
84
+ # interval.stop -> bool or Float
85
+ #
86
+ # mark the stop of the interval. Calling stop on an already stopped interval
87
+ # has no effect. An interval can only be stopped once. If the interval is
88
+ # truely stopped then the duration is returned, otherwise +false+.
89
+ def stop
90
+ raise Error, "Attempt to stop an interval that has not started" unless started?
91
+ return false if stopped?
92
+
93
+ @stop_instant = ::Hitimes.raw_instant
94
+
95
+ return duration
96
+ end
97
+
98
+ # call-seq:
99
+ # interval.duration_so_far -> Float or false
100
+ #
101
+ # return how the duration so far. This will return the duration from the time
102
+ # the Interval was started if the interval is running, otherwise it will return
103
+ # false.
104
+ def duration_so_far
105
+ return false unless running?
106
+
107
+ _now = Hitimes.raw_instant
108
+ calculate_duration(@start_instant, _now)
109
+ end
110
+
111
+ # call-seq:
112
+ # interval.started? -> boolean
113
+ #
114
+ # returns whether or not the interval has been started
115
+ def started?
116
+ !!@start_instant
117
+ end
118
+
119
+ # call-seq:
120
+ # interval.stopped? -> boolean
121
+ #
122
+ # returns whether or not the interval has been stopped
123
+ def stopped?
124
+ !!@stop_instant
125
+ end
126
+
127
+ # call-seq:
128
+ # interval.running? -> boolean
129
+ #
130
+ # returns whether or not the interval is running or not. This means that it
131
+ # has started, but not stopped.
132
+ #
133
+ def running?
134
+ started? && !stopped?
135
+ end
136
+
137
+ # call-seq:
138
+ # interval.duration -> Float
139
+ # interval.to_f -> Float
140
+ # interval.to_seconds -> Float
141
+ # interval.length -> Float
142
+ #
143
+ # Returns the Float value of the interval, the value is in seconds. If the
144
+ # interval has not had stop called yet, it will report the number of seconds
145
+ # in the interval up to the current point in time.
146
+ #
147
+ # Raises Error if duration is called on an interval that has not started yet.
148
+ #
149
+ def duration
150
+ raise Error, "Attempt to report a duration on an interval that has not started" unless started?
151
+
152
+ return duration_so_far unless stopped?
153
+
154
+ if @duration < 0 then
155
+ @duration = calculate_duration(@start_instant, @stop_instant)
156
+ end
157
+
158
+ return @duration
159
+ end
160
+
161
+ alias to_f duration
162
+ alias to_seconds duration
163
+ alias length duration
164
+
165
+ private
166
+
167
+ def calculate_duration(start, stop)
168
+ (stop - start) / ::Hitimes::INSTANT_CONVERSION_FACTOR
169
+ end
170
+ end
171
+ end