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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b8e1ebec45b236ad05a903e06863a0d6579a60d0
4
- data.tar.gz: 44b923bde167cd85317add07f1a2a42f9657563e
3
+ metadata.gz: fbbba71c8a07c8110549bfcee7445288c8ed3172
4
+ data.tar.gz: 8c725fa5f1de381ce76f668e52c7735d87a1429f
5
5
  SHA512:
6
- metadata.gz: 3985319ebe5dab0ade521e48fcd4a1d108f74f11d639aa6c9e2bd77d2ecb8b2599d14002108be5faf602f538887484ef999432eef20235642ad47b9b395623b2
7
- data.tar.gz: ecedf4dd5f8777404e151a4753e350c1e6bdd029b86882a4ad498dcb0be478ae762a81858a7dff727107fa21597000229e48783c988fbdbc2f6558408d97c9c7
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
@@ -26,6 +26,7 @@ module ZTK
26
26
  require 'ztk/locator'
27
27
  require 'ztk/logger'
28
28
  require 'ztk/parallel'
29
+ require 'ztk/profiler'
29
30
  require 'ztk/pty'
30
31
  require 'ztk/report'
31
32
  require 'ztk/rescue_retry'
@@ -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
- # = Typical usage:
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
- # = Simple logger chain:
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
- # = Alternate logger chaining:
39
+ # *Alternate logger chaining*:
40
40
  #
41
41
  # logger = ZTK::Logger.new(STDOUT)
42
42
  # logger.loggers << ::Logger.new('test.log')
@@ -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
@@ -1,6 +1,6 @@
1
1
  module ZTK
2
2
 
3
3
  # ZTK Version String
4
- VERSION = "2.3.1"
4
+ VERSION = "2.4.0"
5
5
 
6
6
  end
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.3.1
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-07-25 00:00:00.000000000 Z
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