ztk 2.3.1 → 2.4.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/README.md +4 -0
- data/lib/ztk.rb +1 -0
- data/lib/ztk/logger.rb +3 -3
- data/lib/ztk/profiler.rb +110 -0
- data/lib/ztk/profiler/core.rb +74 -0
- data/lib/ztk/profiler/private.rb +52 -0
- data/lib/ztk/profiler/timer.rb +33 -0
- data/lib/ztk/profiler/timer/class_methods.rb +76 -0
- data/lib/ztk/version.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fbbba71c8a07c8110549bfcee7445288c8ed3172
|
4
|
+
data.tar.gz: 8c725fa5f1de381ce76f668e52c7735d87a1429f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ebd5505c5e8607536a054788d545432011aae08f3243cf9614e9c87c17567009784f014d6dbbc0141e0f117dab5ea3fa0b88dc93f0ed6163a5b280cb81d4de1
|
7
|
+
data.tar.gz: 96e9aa8493a4336e5723df3f3f6aed28856108cef55f16c76208cea07cff583895e92ed122d3125c3bc50276806678a957c3250a03747516b301d3507c71ce6f
|
data/README.md
CHANGED
@@ -44,6 +44,10 @@ Zachary's Tool Kit contains a collection of reusable classes meant to simplify d
|
|
44
44
|
|
45
45
|
Easily turn linear iterative tasks into parallel tasks and leverage multiple cores to speed up processing of your large sets of data. Read more at the [ZTK::Parallel](http://zpatten.github.io/ztk/ZTK/Parallel.html) documentation.
|
46
46
|
|
47
|
+
- **ZTK::Profiler**
|
48
|
+
|
49
|
+
Build timing profiles easily with this class. Allows for arbitrary nesting of profiles and provides full reporting. Read more at the [ZTK::Profiler](http://zpatten.github.io/ztk/ZTK/Profiler.html) documentation.
|
50
|
+
|
47
51
|
- **ZTK::Report**
|
48
52
|
|
49
53
|
Console based reporting class which allows you to easily output either list or spreadsheet based reports from sets of data. Read more at the [ZTK::Report](http://zpatten.github.io/ztk/ZTK/Report.html) documentation.
|
data/lib/ztk.rb
CHANGED
data/lib/ztk/logger.rb
CHANGED
@@ -18,7 +18,7 @@ module ZTK
|
|
18
18
|
# use this library like so:
|
19
19
|
# LOG_LEVEL=DEBUG bin/cucumber-chef ssh
|
20
20
|
#
|
21
|
-
#
|
21
|
+
# *Typical usage*:
|
22
22
|
#
|
23
23
|
# $logger = ZTK::Logger.new("/dev/null")
|
24
24
|
#
|
@@ -28,7 +28,7 @@ module ZTK
|
|
28
28
|
# $logger.error { "This is a error message!" }
|
29
29
|
# $logger.fatal { "This is a fatal message!" }
|
30
30
|
#
|
31
|
-
#
|
31
|
+
# *Simple logger chain*:
|
32
32
|
#
|
33
33
|
# logger = ZTK::Logger.new
|
34
34
|
# logger.loggers << ::Logger.new(STDOUT)
|
@@ -36,7 +36,7 @@ module ZTK
|
|
36
36
|
#
|
37
37
|
# logger.debug { "This will be written to STDOUT as well as test.log!" }
|
38
38
|
#
|
39
|
-
#
|
39
|
+
# *Alternate logger chaining*:
|
40
40
|
#
|
41
41
|
# logger = ZTK::Logger.new(STDOUT)
|
42
42
|
# logger.loggers << ::Logger.new('test.log')
|
data/lib/ztk/profiler.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
|
3
|
+
module ZTK
|
4
|
+
|
5
|
+
# Profiler Error Class
|
6
|
+
#
|
7
|
+
# @author Zachary Patten <zachary AT jovelabs DOT com>
|
8
|
+
class ProfilerError < Error; end
|
9
|
+
|
10
|
+
# Profiler Class
|
11
|
+
#
|
12
|
+
# A comprehensive timing profiler, this class functions using method_missing
|
13
|
+
# to allow the consumer to define timing profiles in an ad hoc manner using
|
14
|
+
# a block.
|
15
|
+
#
|
16
|
+
# *Example Code*:
|
17
|
+
#
|
18
|
+
# ZTK::Profiler.reset
|
19
|
+
#
|
20
|
+
# ZTK::Profiler.operation_alpha do
|
21
|
+
# ZTK::Profiler.operation_one do
|
22
|
+
# ZTK::Profiler.operation_a do
|
23
|
+
# sleep(0.1)
|
24
|
+
# end
|
25
|
+
# ZTK::Profiler.operation_b do
|
26
|
+
# sleep(0.1)
|
27
|
+
# end
|
28
|
+
# ZTK::Profiler.operation_c do
|
29
|
+
# sleep(0.1)
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
# ZTK::Profiler.operation_two do
|
33
|
+
# ZTK::Profiler.operation_d do
|
34
|
+
# sleep(0.1)
|
35
|
+
# end
|
36
|
+
# ZTK::Profiler.operation_e do
|
37
|
+
# sleep(0.1)
|
38
|
+
# end
|
39
|
+
# ZTK::Profiler.operation_f do
|
40
|
+
# sleep(0.1)
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
# end
|
44
|
+
# ZTK::Profiler.operation_beta do
|
45
|
+
# ZTK::Profiler.operation_three do
|
46
|
+
# ZTK::Profiler.operation_a do
|
47
|
+
# sleep(0.1)
|
48
|
+
# end
|
49
|
+
# ZTK::Profiler.operation_b do
|
50
|
+
# sleep(0.1)
|
51
|
+
# end
|
52
|
+
# ZTK::Profiler.operation_c do
|
53
|
+
# sleep(0.1)
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# ZTK::Profiler.report
|
59
|
+
#
|
60
|
+
# *Example Output*:
|
61
|
+
#
|
62
|
+
# --+ OperationAlpha 0.6070s
|
63
|
+
# |--+ OperationOne 0.3035s
|
64
|
+
# | |--+ OperationA 0.1011s
|
65
|
+
# | |--+ OperationB 0.1011s
|
66
|
+
# | |--+ OperationC 0.1011s
|
67
|
+
# |--+ OperationTwo 0.3035s
|
68
|
+
# | |--+ OperationD 0.1011s
|
69
|
+
# | |--+ OperationE 0.1011s
|
70
|
+
# | |--+ OperationF 0.1011s
|
71
|
+
# --+ OperationBeta 0.3034s
|
72
|
+
# |--+ OperationThree 0.3034s
|
73
|
+
# | |--+ OperationA 0.1011s
|
74
|
+
# | |--+ OperationB 0.1011s
|
75
|
+
# | |--+ OperationC 0.1011s
|
76
|
+
#
|
77
|
+
# OperationAlpha: 0.6070s (22.2%)
|
78
|
+
# OperationOne: 0.3035s (11.1%)
|
79
|
+
# OperationA: 0.2022s (7.4%)
|
80
|
+
# OperationB: 0.2022s (7.4%)
|
81
|
+
# OperationC: 0.2022s (7.4%)
|
82
|
+
# OperationTwo: 0.3035s (11.1%)
|
83
|
+
# OperationD: 0.1011s (3.7%)
|
84
|
+
# OperationE: 0.1011s (3.7%)
|
85
|
+
# OperationF: 0.1011s (3.7%)
|
86
|
+
# OperationBeta: 0.3034s (11.1%)
|
87
|
+
# OperationThree: 0.3034s (11.1%)
|
88
|
+
#
|
89
|
+
# Nested Time: 2.7306s
|
90
|
+
# Actual Time: 0.9110s
|
91
|
+
# Profiled Time: 0.9105s
|
92
|
+
# Missing Time: 0.0005s
|
93
|
+
#
|
94
|
+
# @author Zachary Patten <zachary AT jovelabs DOT com>
|
95
|
+
class Profiler
|
96
|
+
|
97
|
+
require 'ztk/profiler/core'
|
98
|
+
require 'ztk/profiler/private'
|
99
|
+
require 'ztk/profiler/timer'
|
100
|
+
|
101
|
+
extend ZTK::Profiler::Core
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
extend ZTK::Profiler::Private
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module ZTK
|
2
|
+
class Profiler
|
3
|
+
|
4
|
+
# Profiler Core Functionality
|
5
|
+
module Core
|
6
|
+
require 'ztk/ui'
|
7
|
+
|
8
|
+
@@start_time ||= nil
|
9
|
+
@@end_time ||= nil
|
10
|
+
@@timer_stack ||= Array.new
|
11
|
+
|
12
|
+
def start
|
13
|
+
reset
|
14
|
+
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
def stop
|
19
|
+
@@end_time ||= Time.now.utc
|
20
|
+
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
def reset
|
25
|
+
@@start_time = Time.now.utc
|
26
|
+
@@end_time = nil
|
27
|
+
@@timer_stack = Array.new
|
28
|
+
Timer.reset
|
29
|
+
|
30
|
+
true
|
31
|
+
end
|
32
|
+
|
33
|
+
def method_missing(method_name, *method_args)
|
34
|
+
raise "You must supply a block to the profiler method #{method_name.inspect}!" unless block_given?
|
35
|
+
|
36
|
+
@@start_time ||= Time.now.utc
|
37
|
+
|
38
|
+
result = nil
|
39
|
+
timer = Timer.new(method_name, @@timer_stack.last)
|
40
|
+
|
41
|
+
@@timer_stack.push(timer)
|
42
|
+
timer.benchmark = ::Benchmark.realtime do
|
43
|
+
result = yield
|
44
|
+
end
|
45
|
+
@@timer_stack.pop
|
46
|
+
|
47
|
+
result
|
48
|
+
end
|
49
|
+
|
50
|
+
def total_time
|
51
|
+
stop
|
52
|
+
@@end_time - @@start_time
|
53
|
+
end
|
54
|
+
|
55
|
+
def report(options={})
|
56
|
+
options = Base.build_config({}, options)
|
57
|
+
|
58
|
+
stop
|
59
|
+
|
60
|
+
results = Array.new
|
61
|
+
|
62
|
+
report_timers(options)
|
63
|
+
options.ui.stdout.puts
|
64
|
+
results << report_timer_totals(options)
|
65
|
+
options.ui.stdout.puts
|
66
|
+
results << report_totals(options)
|
67
|
+
|
68
|
+
results
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module ZTK
|
2
|
+
class Profiler
|
3
|
+
|
4
|
+
# Profiler Private Functionality
|
5
|
+
module Private
|
6
|
+
|
7
|
+
def report_timers(options={}, parent=nil, depth=0)
|
8
|
+
child_timers = Timer.timers_by_parent[parent]
|
9
|
+
child_timers.each do |timer|
|
10
|
+
prefix = (' |' * (depth))
|
11
|
+
|
12
|
+
options.ui.stdout.print("%s--+ %s %0.4fs\n" % [ prefix, timer.name.to_s.camelize, timer.benchmark ])
|
13
|
+
|
14
|
+
report_timers(options, timer, (depth + 1))
|
15
|
+
end
|
16
|
+
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
def report_timer_totals(options={})
|
21
|
+
result = Hash.new
|
22
|
+
timer_names = Timer.timers_by_name.keys.compact
|
23
|
+
timer_names_camelize = timer_names.map(&:to_s).map(&:camelize)
|
24
|
+
max_timer_name_length = (timer_names_camelize.map(&:length).max + 1)
|
25
|
+
timer_names.each do |timer_name|
|
26
|
+
benchmark_nested = Timer.timers_by_name[timer_name].map(&:benchmark_nested).reduce(&:+)
|
27
|
+
result[timer_name] = benchmark_nested
|
28
|
+
|
29
|
+
options.ui.stdout.print("%#{max_timer_name_length}s: %0.4fs (%-3.1f%%)\n" % [timer_name.to_s.camelize, benchmark_nested, (benchmark_nested / Timer.benchmark_nested_total) * 100])
|
30
|
+
end
|
31
|
+
result
|
32
|
+
end
|
33
|
+
|
34
|
+
def report_totals(options={})
|
35
|
+
times = {
|
36
|
+
'Nested Time' => Timer.benchmark_nested_total,
|
37
|
+
'Actual Time' => Profiler.total_time,
|
38
|
+
'Profiled Time' => Timer.total_time,
|
39
|
+
'Missing Time' => (Profiler.total_time - Timer.total_time)
|
40
|
+
}
|
41
|
+
max_key_length = (times.keys.map(&:length).max + 1)
|
42
|
+
time_format = "%#{max_key_length}s: %0.4fs\n"
|
43
|
+
|
44
|
+
times.each do |name, time|
|
45
|
+
options.ui.stdout.print(time_format % [ name, time ])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ZTK
|
2
|
+
class Profiler
|
3
|
+
|
4
|
+
# Profiler Timer Functionality
|
5
|
+
class Timer
|
6
|
+
require 'ztk/profiler/timer/class_methods'
|
7
|
+
|
8
|
+
extend ZTK::Profiler::Timer::ClassMethods
|
9
|
+
|
10
|
+
attr_accessor :name
|
11
|
+
attr_accessor :parent
|
12
|
+
attr_accessor :benchmark
|
13
|
+
|
14
|
+
def initialize(name, parent=nil)
|
15
|
+
self.name = name
|
16
|
+
self.parent = parent
|
17
|
+
|
18
|
+
self.class.add(self)
|
19
|
+
end
|
20
|
+
|
21
|
+
def nested_time
|
22
|
+
@nested_time ||= self.class.nested_time(self.name, self)
|
23
|
+
@nested_time
|
24
|
+
end
|
25
|
+
|
26
|
+
def benchmark_nested
|
27
|
+
(self.benchmark - self.nested_time)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module ZTK
|
2
|
+
class Profiler
|
3
|
+
class Timer
|
4
|
+
|
5
|
+
# Profiler Timer Class Functionality
|
6
|
+
module ClassMethods
|
7
|
+
|
8
|
+
@@timers ||= Array.new
|
9
|
+
@@timers_by_name ||= Hash.new { |hash, key| hash[key] = Array.new }
|
10
|
+
@@timers_by_parent ||= Hash.new { |hash, key| hash[key] = Array.new }
|
11
|
+
@@benchmark_total ||= nil
|
12
|
+
@@benchmark_nested_total ||= nil
|
13
|
+
|
14
|
+
def timers
|
15
|
+
@@timers
|
16
|
+
end
|
17
|
+
|
18
|
+
def timers_by_parent
|
19
|
+
@@timers_by_parent
|
20
|
+
end
|
21
|
+
|
22
|
+
def timers_by_name
|
23
|
+
@@timers_by_name
|
24
|
+
end
|
25
|
+
|
26
|
+
def add(timer)
|
27
|
+
@@timers << timer
|
28
|
+
|
29
|
+
@@timers_by_parent[timer.parent] << timer
|
30
|
+
@@timers_by_name[timer.name] << timer
|
31
|
+
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
def reset
|
36
|
+
@@timers = Array.new
|
37
|
+
@@timers_by_name = Hash.new { |hash, key| hash[key] = Array.new }
|
38
|
+
@@timers_by_parent = Hash.new { |hash, key| hash[key] = Array.new }
|
39
|
+
|
40
|
+
true
|
41
|
+
end
|
42
|
+
|
43
|
+
def nested_time(name=nil, parent=nil)
|
44
|
+
result = 0.0
|
45
|
+
|
46
|
+
child_timers = @@timers_by_parent[parent]
|
47
|
+
child_timers.each do |child_timer|
|
48
|
+
if (child_timer.name == name)
|
49
|
+
result += child_timer.benchmark_nested
|
50
|
+
end
|
51
|
+
result += nested_time(name, child_timer)
|
52
|
+
end
|
53
|
+
|
54
|
+
result
|
55
|
+
end
|
56
|
+
|
57
|
+
def benchmark_total
|
58
|
+
@@benchmark_total ||= @@timers.map(&:benchmark).reduce(&:+)
|
59
|
+
@@benchmark_total
|
60
|
+
end
|
61
|
+
|
62
|
+
def benchmark_nested_total
|
63
|
+
@@benchmark_nested_total ||= @@timers.map(&:benchmark_nested).reduce(&:+)
|
64
|
+
@@benchmark_nested_total
|
65
|
+
end
|
66
|
+
|
67
|
+
def total_time
|
68
|
+
@@total_time ||= @@timers_by_parent[nil].map(&:benchmark).reduce(&:+)
|
69
|
+
@@total_time
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/ztk/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ztk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zachary Patten
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -315,6 +315,11 @@ files:
|
|
315
315
|
- lib/ztk/locator.rb
|
316
316
|
- lib/ztk/logger.rb
|
317
317
|
- lib/ztk/parallel.rb
|
318
|
+
- lib/ztk/profiler.rb
|
319
|
+
- lib/ztk/profiler/core.rb
|
320
|
+
- lib/ztk/profiler/private.rb
|
321
|
+
- lib/ztk/profiler/timer.rb
|
322
|
+
- lib/ztk/profiler/timer/class_methods.rb
|
318
323
|
- lib/ztk/pty.rb
|
319
324
|
- lib/ztk/rake/docs.rb
|
320
325
|
- lib/ztk/report.rb
|