evt-diagnostics-sample 0.0.0.1 → 0.1.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 +4 -4
- data/lib/diagnostics/sample.rb +11 -0
- data/lib/diagnostics/sample/controls.rb +4 -0
- data/lib/diagnostics/sample/controls/clock.rb +58 -0
- data/lib/diagnostics/sample/controls/time.rb +7 -0
- data/lib/diagnostics/sample/defaults.rb +17 -0
- data/lib/diagnostics/sample/log.rb +1 -1
- data/lib/diagnostics/sample/measure.rb +64 -0
- data/lib/diagnostics/sample/measure/clock.rb +22 -0
- data/lib/diagnostics/sample/result.rb +40 -0
- data/lib/diagnostics/sample/sample.rb +64 -0
- metadata +37 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b6d0f5e4778b4584977955ca08b46df3df2278447dc87eeb9155a27a7d87f79d
|
4
|
+
data.tar.gz: cbc2304f16628b0e17520f0c73252c76cc733fbbb3357be4b9bbbd19e8af8aba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fae5a8f6b0578d2c28f3fe7a68e0036b4acc23a410dca001296f0e275a08595b034f95f83471175bcbceb82cc7a807686c8b44c5a675db773c878282d2987f63
|
7
|
+
data.tar.gz: 6d9c12df6b21dccb70534c67116201cab94e0eb1484d320e0763a88390a522eeec46795ab315cb3854474e5361a7e601ae1aeb40e1f9b12d3e1fe8073757c2b8
|
data/lib/diagnostics/sample.rb
CHANGED
@@ -1,4 +1,15 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
|
3
|
+
require 'clock'
|
4
|
+
require 'configure'
|
5
|
+
require 'dependency'
|
1
6
|
require 'log'
|
7
|
+
require 'schema'
|
2
8
|
|
9
|
+
require 'diagnostics/sample/defaults'
|
3
10
|
require 'diagnostics/sample/log'
|
11
|
+
require 'diagnostics/sample/measure'
|
12
|
+
require 'diagnostics/sample/measure/clock'
|
13
|
+
require 'diagnostics/sample/result'
|
14
|
+
|
4
15
|
require 'diagnostics/sample/sample'
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Diagnostics
|
2
|
+
class Sample
|
3
|
+
module Controls
|
4
|
+
module Clock
|
5
|
+
def self.example(**args)
|
6
|
+
Incrementing.example(**args)
|
7
|
+
end
|
8
|
+
|
9
|
+
class Incrementing
|
10
|
+
def elapsed_seconds
|
11
|
+
@elapsed_seconds ||= 0
|
12
|
+
end
|
13
|
+
attr_writer :elapsed_seconds
|
14
|
+
|
15
|
+
initializer :start_time, :interval_nanoseconds
|
16
|
+
|
17
|
+
def self.build(interval: nil, start_time: nil)
|
18
|
+
interval ||= Defaults.interval_seconds
|
19
|
+
start_time ||= Defaults.start_time
|
20
|
+
|
21
|
+
interval_nanoseconds = interval * 1_000_000
|
22
|
+
|
23
|
+
new(start_time, interval_nanoseconds)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.example(**args)
|
27
|
+
build(**args)
|
28
|
+
end
|
29
|
+
|
30
|
+
def next
|
31
|
+
offset = elapsed_seconds
|
32
|
+
|
33
|
+
self.elapsed_seconds += interval_nanoseconds
|
34
|
+
|
35
|
+
start_time_nanoseconds + offset
|
36
|
+
end
|
37
|
+
|
38
|
+
def start_time_nanoseconds
|
39
|
+
start_time.to_i * 1_000_000
|
40
|
+
end
|
41
|
+
|
42
|
+
alias_method :now, :next
|
43
|
+
|
44
|
+
module Defaults
|
45
|
+
def self.interval_seconds
|
46
|
+
1
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.start_time
|
50
|
+
Time.example
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Diagnostics
|
2
|
+
class Sample
|
3
|
+
class Measure
|
4
|
+
include Log::Dependency
|
5
|
+
extend Configure::Macro
|
6
|
+
|
7
|
+
configure :measure
|
8
|
+
|
9
|
+
dependency :clock, Clock
|
10
|
+
|
11
|
+
attr_writer :gc
|
12
|
+
def gc
|
13
|
+
@gc ||= Defaults.gc
|
14
|
+
end
|
15
|
+
|
16
|
+
initializer :action
|
17
|
+
|
18
|
+
def configure(gc: nil)
|
19
|
+
self.gc = gc unless gc.nil?
|
20
|
+
|
21
|
+
Clock.configure(self)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.build(gc: nil, action: nil, &block_action)
|
25
|
+
action ||= block_action
|
26
|
+
|
27
|
+
instance = new(action)
|
28
|
+
instance.configure(gc: gc)
|
29
|
+
instance
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.call(gc: nil, action: nil, &block_action)
|
33
|
+
instance = build(gc: gc, action: action, &block_action)
|
34
|
+
instance.()
|
35
|
+
end
|
36
|
+
|
37
|
+
def call
|
38
|
+
logger.trace { "Measuring action (GC: #{gc.inspect})" }
|
39
|
+
|
40
|
+
::GC.disable unless gc
|
41
|
+
|
42
|
+
start_time = clock.now
|
43
|
+
|
44
|
+
action.()
|
45
|
+
|
46
|
+
end_time = clock.now
|
47
|
+
|
48
|
+
::GC.enable unless gc
|
49
|
+
|
50
|
+
elapsed_time = end_time - start_time
|
51
|
+
|
52
|
+
logger.trace { "Action measured (GC: #{gc.inspect}, Elapsed Time: #{LogText.elapsed_time_milliseconds(elapsed_time)})" }
|
53
|
+
|
54
|
+
elapsed_time
|
55
|
+
end
|
56
|
+
|
57
|
+
module LogText
|
58
|
+
def self.elapsed_time_milliseconds(elapsed_time_nanoseconds)
|
59
|
+
"%fms" % Rational(elapsed_time_nanoseconds, 1_000_000)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Diagnostics
|
2
|
+
class Sample
|
3
|
+
class Measure
|
4
|
+
class Clock
|
5
|
+
extend ::Configure::Macro
|
6
|
+
|
7
|
+
self.default_factory_method = :new
|
8
|
+
|
9
|
+
configure :clock
|
10
|
+
|
11
|
+
def now
|
12
|
+
Process.clock_gettime(
|
13
|
+
Process::CLOCK_MONOTONIC,
|
14
|
+
:nanosecond
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
Substitute = ::Clock::UTC::Substitute
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Diagnostics
|
2
|
+
class Sample
|
3
|
+
class Result
|
4
|
+
include Schema::DataStructure
|
5
|
+
|
6
|
+
attribute :cycles, Integer, default: 0
|
7
|
+
attribute :cycle_time_milliseconds, Float, default: 0.0
|
8
|
+
attribute :warmup_cycles, Integer, default: 0
|
9
|
+
attribute :warmup_cycle_time_milliseconds, Float, default: 0.0
|
10
|
+
|
11
|
+
def cycle(elapsed_time)
|
12
|
+
self.cycle_time_milliseconds += elapsed_time
|
13
|
+
|
14
|
+
self.cycles += 1
|
15
|
+
end
|
16
|
+
|
17
|
+
def warmup_cycle(elapsed_time)
|
18
|
+
self.warmup_cycle_time_milliseconds += elapsed_time
|
19
|
+
|
20
|
+
self.warmup_cycles += 1
|
21
|
+
end
|
22
|
+
|
23
|
+
def mean_cycle_time_milliseconds
|
24
|
+
cycle_time_milliseconds / cycles
|
25
|
+
end
|
26
|
+
|
27
|
+
def mean_warmup_cycle_time_milliseconds
|
28
|
+
warmup_cycle_time_milliseconds / warmup_cycles
|
29
|
+
end
|
30
|
+
|
31
|
+
def cycle_frequency
|
32
|
+
cycles / (cycle_time_milliseconds / 1_000)
|
33
|
+
end
|
34
|
+
|
35
|
+
def warmup_cycle_frequency
|
36
|
+
warmup_cycles / (warmup_cycle_time_milliseconds / 1_000)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Diagnostics
|
2
|
+
class Sample
|
3
|
+
include Log::Dependency
|
4
|
+
|
5
|
+
dependency :measure, Measure
|
6
|
+
|
7
|
+
def configure(action: nil, gc: nil)
|
8
|
+
Measure.configure(self, action: action, gc: gc)
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_writer :cycles
|
12
|
+
def cycles
|
13
|
+
@cycles ||= Defaults.cycles
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_writer :warmup_cycles
|
17
|
+
def warmup_cycles
|
18
|
+
@warmup_cycles ||= Defaults.warmup_cycles
|
19
|
+
end
|
20
|
+
|
21
|
+
def result
|
22
|
+
@result ||= Result.new
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.build(cycles=nil, warmup_cycles: nil, gc: nil, &action)
|
26
|
+
instance = new
|
27
|
+
|
28
|
+
instance.cycles = cycles unless cycles.nil?
|
29
|
+
instance.warmup_cycles = warmup_cycles unless warmup_cycles.nil?
|
30
|
+
|
31
|
+
instance.configure(action: action, gc: gc)
|
32
|
+
instance
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.call(cycles=nil, warmup_cycles: nil, gc: nil, &action)
|
36
|
+
instance = build(cycles, warmup_cycles: warmup_cycles, gc: gc, &action)
|
37
|
+
instance.()
|
38
|
+
end
|
39
|
+
|
40
|
+
def call
|
41
|
+
logger.trace { "Starting warmup (Warmup Cycles: #{warmup_cycles})" }
|
42
|
+
|
43
|
+
warmup_cycles.times do
|
44
|
+
elapsed_time = measure.()
|
45
|
+
|
46
|
+
result.warmup_cycle(elapsed_time)
|
47
|
+
end
|
48
|
+
|
49
|
+
logger.debug { "Finished warmup (Warmup Cycles: #{warmup_cycles})" }
|
50
|
+
|
51
|
+
logger.trace { "Starting sample (Cycles: #{cycles}, Warmup Cycles: #{warmup_cycles})" }
|
52
|
+
|
53
|
+
cycles.times do
|
54
|
+
elapsed_time = measure.()
|
55
|
+
|
56
|
+
result.cycle(elapsed_time)
|
57
|
+
end
|
58
|
+
|
59
|
+
logger.info { "Finished sample (Cycles: #{cycles}, Warmup Cycles: #{warmup_cycles}, Mean Cycle Time: #{result.mean_cycle_time_milliseconds}ms)" }
|
60
|
+
|
61
|
+
result
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: evt-diagnostics-sample
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.0
|
4
|
+
version: 0.1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- The Eventide Project
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: evt-log
|
@@ -24,6 +24,34 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: evt-configure
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: evt-schema
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: test_bench
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -46,7 +74,13 @@ extra_rdoc_files: []
|
|
46
74
|
files:
|
47
75
|
- lib/diagnostics/sample.rb
|
48
76
|
- lib/diagnostics/sample/controls.rb
|
77
|
+
- lib/diagnostics/sample/controls/clock.rb
|
78
|
+
- lib/diagnostics/sample/controls/time.rb
|
79
|
+
- lib/diagnostics/sample/defaults.rb
|
49
80
|
- lib/diagnostics/sample/log.rb
|
81
|
+
- lib/diagnostics/sample/measure.rb
|
82
|
+
- lib/diagnostics/sample/measure/clock.rb
|
83
|
+
- lib/diagnostics/sample/result.rb
|
50
84
|
- lib/diagnostics/sample/sample.rb
|
51
85
|
homepage: https://github.com/eventide-project/diagnostics-sample
|
52
86
|
licenses:
|
@@ -68,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
68
102
|
version: '0'
|
69
103
|
requirements: []
|
70
104
|
rubyforge_project:
|
71
|
-
rubygems_version: 2.7.
|
105
|
+
rubygems_version: 2.7.6
|
72
106
|
signing_key:
|
73
107
|
specification_version: 4
|
74
108
|
summary: Sampling and measurement of execution cycles
|