hitimes 1.3.1 → 2.0.0

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.
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