ztk 2.3.1 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|