benelux 0.2.0.001 → 0.3.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.
- data/CHANGES.txt +5 -1
- data/README.rdoc +6 -2
- data/benelux.gemspec +10 -2
- data/lib/benelux.rb +161 -45
- data/lib/benelux/mark.rb +23 -20
- data/lib/benelux/mixins/thread.rb +2 -1
- data/lib/benelux/range.rb +50 -0
- data/lib/benelux/stats.rb +193 -0
- data/lib/benelux/tags.rb +110 -0
- data/lib/benelux/timeline.rb +127 -38
- data/tryouts/10_stats_tryouts.rb +49 -0
- data/tryouts/11_tags_tryouts.rb +60 -0
- data/tryouts/{basic_tryouts.rb → 20_class_methods_tryouts.rb} +4 -4
- data/tryouts/30_timeline_tryouts.rb +25 -0
- data/tryouts/proofs/alias_performance.rb +33 -0
- data/tryouts/proofs/timer_threading.rb +30 -0
- metadata +11 -3
data/CHANGES.txt
CHANGED
data/README.rdoc
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
-
= Benelux v0.
|
1
|
+
= Benelux v0.3 (IN PROGRESS)
|
2
2
|
|
3
|
-
<b
|
3
|
+
<b>A madhouse of timers for your Ruby codes</b>
|
4
4
|
|
5
5
|
|
6
6
|
== Features
|
7
7
|
|
8
|
+
* Create timers for any Ruby method
|
9
|
+
* Granular statistics
|
8
10
|
|
9
11
|
|
10
12
|
== Installation
|
@@ -21,6 +23,7 @@ Get it in one of the following ways:
|
|
21
23
|
* Codes[http://github.com/delano/benelux]
|
22
24
|
* RDocs[http://delano.github.com/benelux]
|
23
25
|
|
26
|
+
|
24
27
|
== Credits
|
25
28
|
|
26
29
|
* Delano Mandelbaum (http://solutious.com)
|
@@ -29,6 +32,7 @@ Get it in one of the following ways:
|
|
29
32
|
== Thanks
|
30
33
|
|
31
34
|
* Alexis Sellier for fielding my Ruby questions
|
35
|
+
* Tara Dougans for the motivational speaches
|
32
36
|
|
33
37
|
|
34
38
|
== License
|
data/benelux.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
@spec = Gem::Specification.new do |s|
|
2
2
|
s.name = "benelux"
|
3
3
|
s.rubyforge_project = 'benelux'
|
4
|
-
s.version = "0.
|
4
|
+
s.version = "0.3.0"
|
5
5
|
s.summary = "Benelux: Little freakin' timers for your Ruby codes"
|
6
6
|
s.description = s.summary
|
7
7
|
s.author = "Delano Mandelbaum"
|
@@ -26,8 +26,16 @@
|
|
26
26
|
lib/benelux.rb
|
27
27
|
lib/benelux/mark.rb
|
28
28
|
lib/benelux/mixins/thread.rb
|
29
|
+
lib/benelux/range.rb
|
30
|
+
lib/benelux/stats.rb
|
31
|
+
lib/benelux/tags.rb
|
29
32
|
lib/benelux/timeline.rb
|
30
|
-
tryouts/
|
33
|
+
tryouts/10_stats_tryouts.rb
|
34
|
+
tryouts/11_tags_tryouts.rb
|
35
|
+
tryouts/20_class_methods_tryouts.rb
|
36
|
+
tryouts/30_timeline_tryouts.rb
|
37
|
+
tryouts/proofs/alias_performance.rb
|
38
|
+
tryouts/proofs/timer_threading.rb
|
31
39
|
)
|
32
40
|
|
33
41
|
|
data/lib/benelux.rb
CHANGED
@@ -1,66 +1,110 @@
|
|
1
1
|
require 'attic'
|
2
|
-
require 'thread'
|
3
2
|
require 'hexoid'
|
3
|
+
require 'thread'
|
4
4
|
|
5
5
|
module Benelux
|
6
|
+
VERSION = "0.3.0"
|
6
7
|
NOTSUPPORTED = [Class, Object, Kernel]
|
7
|
-
SUFFIX_START = :a.freeze
|
8
|
-
SUFFIX_END = :z.freeze
|
9
8
|
|
10
|
-
|
9
|
+
class BeneluxError < RuntimeError; end
|
10
|
+
class NotSupported < BeneluxError; end
|
11
|
+
class NoTrack < BeneluxError; end
|
12
|
+
|
13
|
+
require 'benelux/tags'
|
11
14
|
require 'benelux/mark'
|
15
|
+
require 'benelux/range'
|
16
|
+
require 'benelux/stats'
|
17
|
+
require 'benelux/timeline'
|
12
18
|
require 'benelux/mixins/thread'
|
13
19
|
|
14
20
|
@@timed_methods = {}
|
15
|
-
@@
|
16
|
-
@@
|
21
|
+
@@known_threads = []
|
22
|
+
@@timelines = {}
|
17
23
|
@@mutex = Mutex.new
|
24
|
+
@@debug = true
|
18
25
|
|
19
|
-
|
20
|
-
|
26
|
+
def Benelux.enable_debug; @@debug = true; end
|
27
|
+
def Benelux.disable_debug; @@debug = false; end
|
28
|
+
def Benelux.debug?; @@debug; end
|
21
29
|
|
30
|
+
# Returns an Array of method names for the current class that
|
31
|
+
# are timed by Benelux.
|
32
|
+
#
|
33
|
+
# This is an instance method for objects which have Benelux
|
34
|
+
# modified methods.
|
22
35
|
def benelux_timers
|
23
36
|
Benelux.timed_methods[self.class]
|
24
37
|
end
|
25
38
|
|
26
|
-
def Benelux.
|
27
|
-
|
39
|
+
def Benelux.timeline(track=nil)
|
40
|
+
if track.nil?
|
41
|
+
if Benelux.timelines.empty?
|
42
|
+
tl = known_threads.collect { |t| t.timeline}
|
43
|
+
else
|
44
|
+
tl = Benelux.timelines.values
|
45
|
+
end
|
46
|
+
Benelux.merge_timelines *tl
|
47
|
+
else
|
48
|
+
Benelux.timelines[track]
|
49
|
+
end
|
28
50
|
end
|
29
51
|
|
30
|
-
|
31
|
-
|
52
|
+
# Must be run in single-threaded mode (after all track threads
|
53
|
+
# have finished).
|
54
|
+
#
|
55
|
+
def Benelux.update_all_track_timelines
|
56
|
+
Benelux.timelines.keys.each { |track| Benelux.update_track_timeline(track) }
|
57
|
+
end
|
58
|
+
|
59
|
+
# Must be run from the master thread in the current track. The master
|
60
|
+
# thread is either the first thread in a track or the one which creates
|
61
|
+
# additional threads for the track.
|
62
|
+
#
|
63
|
+
def Benelux.update_track_timeline(track=nil)
|
64
|
+
track = Thread.current.track if track.nil?
|
65
|
+
threads = Benelux.known_threads.select { |t| t.track == track }
|
66
|
+
Benelux.timelines[track] = Benelux.merge_timelines(*threads.collect { |t| t.timeline })
|
67
|
+
threads.each { |t| t.timeline.clear }
|
68
|
+
Benelux.timelines[track]
|
69
|
+
end
|
70
|
+
|
71
|
+
# If +track+ is specified, this will associate the current
|
72
|
+
# thread with that +track+.
|
73
|
+
#
|
74
|
+
# If +track+ is nil, it returns the timeline for the
|
75
|
+
# track associated to the current thread.
|
76
|
+
#
|
77
|
+
def Benelux.current_track(track=nil)
|
78
|
+
if track.nil?
|
79
|
+
raise NoTrack if Benelux.timelines[Thread.current.track].nil?
|
80
|
+
return Benelux.timelines[Thread.current.track]
|
81
|
+
end
|
82
|
+
Benelux.store_thread_reference
|
32
83
|
@@mutex.synchronize do
|
33
|
-
|
84
|
+
# QUESTION: Is it okay for multiple threads to write to
|
85
|
+
# different elements in the same hash?
|
86
|
+
Benelux.timelines[track] ||= Benelux::Timeline.new
|
87
|
+
Benelux.add_thread_tags :track => track
|
88
|
+
Thread.current.track = track
|
34
89
|
end
|
35
90
|
end
|
36
91
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
def Benelux.timeline
|
46
|
-
@@timeline = Benelux.generate_timeline if @@timeline.empty?
|
47
|
-
@@timeline
|
48
|
-
end
|
49
|
-
|
50
|
-
def Benelux.generate_timeline
|
51
|
-
@@mutex.synchronize do
|
52
|
-
timeline = Benelux::Timeline.new
|
53
|
-
Benelux.thread_timelines.each { |t| timeline << t.benelux }
|
54
|
-
timeline.flatten.sort
|
92
|
+
# Combine two or more timelines into a new, single Benelux::Timeline.
|
93
|
+
#
|
94
|
+
def Benelux.merge_timelines(*timelines)
|
95
|
+
tl, stats, ranges = Benelux::Timeline.new, Benelux::Stats.new, []
|
96
|
+
timelines.each do |t|
|
97
|
+
tl += t
|
55
98
|
end
|
99
|
+
tl
|
56
100
|
end
|
57
101
|
|
58
|
-
def Benelux.thread_timeline
|
59
|
-
Thread.current.
|
60
|
-
Thread.current.
|
102
|
+
def Benelux.thread_timeline
|
103
|
+
Thread.current.timeline ||= Benelux::Timeline.new
|
104
|
+
Thread.current.timeline
|
61
105
|
end
|
62
106
|
|
63
|
-
|
107
|
+
# Make note of the class which included Benelux.
|
64
108
|
def Benelux.included(klass)
|
65
109
|
timed_methods[klass] = [] unless timed_methods.has_key? klass
|
66
110
|
end
|
@@ -75,7 +119,7 @@ module Benelux
|
|
75
119
|
prepare_object klass
|
76
120
|
meth_alias = rename_method klass, meth
|
77
121
|
timed_methods[klass] << meth
|
78
|
-
klass.module_eval generate_timer_str(meth_alias, meth)
|
122
|
+
klass.module_eval generate_timer_str(meth_alias, meth), __FILE__, 215
|
79
123
|
end
|
80
124
|
|
81
125
|
def Benelux.add_tally obj, meth
|
@@ -85,15 +129,75 @@ module Benelux
|
|
85
129
|
names.flatten.collect { |n| n.to_s }.join('_')
|
86
130
|
end
|
87
131
|
|
88
|
-
|
132
|
+
|
89
133
|
def Benelux.prepare_object obj
|
90
134
|
obj.extend Attic unless obj.kind_of?(Attic)
|
91
135
|
unless obj.kind_of?(Benelux)
|
92
|
-
obj.attic :
|
136
|
+
obj.attic :timeline
|
93
137
|
obj.send :include, Benelux
|
94
138
|
end
|
95
139
|
end
|
140
|
+
|
141
|
+
# Benelux keeps track of the threads which have timed
|
142
|
+
# objects so it can process the timelines after all is
|
143
|
+
# said and done.
|
144
|
+
def Benelux.store_thread_reference
|
145
|
+
return if Benelux.known_threads.member? Thread.current
|
146
|
+
@@mutex.synchronize do
|
147
|
+
Thread.current.timeline ||= Benelux::Timeline.new
|
148
|
+
Benelux.known_threads << Thread.current
|
149
|
+
Benelux.known_threads.uniq!
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# Thread tags become the default for any new Mark or Range.
|
154
|
+
def Benelux.add_thread_tags(args=Benelux::Tags.new)
|
155
|
+
Benelux.thread_timeline.add_default_tags args
|
156
|
+
end
|
157
|
+
def Benelux.add_thread_tag(*args) add_thread_tags *args end
|
158
|
+
|
159
|
+
def Benelux.remove_thread_tags(*args)
|
160
|
+
Benelux.thread_timeline.remove_default_tags *args
|
161
|
+
end
|
162
|
+
def Benelux.remove_thread_tag(*args) remove_thread_tags *args end
|
163
|
+
|
164
|
+
def Benelux.tracks
|
165
|
+
Benelux.timelines.keys
|
166
|
+
end
|
167
|
+
|
168
|
+
def Benelux.inspect
|
169
|
+
str = ["Benelux"]
|
170
|
+
str << "threads:" << Benelux.known_threads.inspect
|
171
|
+
str << "tracks:" << Benelux.tracks.inspect
|
172
|
+
str << "timers:" << Benelux.timed_methods.inspect
|
173
|
+
str << "timeline:" << Benelux.timeline.inspect
|
174
|
+
str.join $/
|
175
|
+
end
|
176
|
+
|
177
|
+
def Benelux.supported?(klass)
|
178
|
+
!NOTSUPPORTED.member?(klass)
|
179
|
+
end
|
180
|
+
|
181
|
+
def Benelux.timed_methods
|
182
|
+
@@timed_methods
|
183
|
+
end
|
184
|
+
|
185
|
+
def Benelux.known_threads
|
186
|
+
@@known_threads
|
187
|
+
end
|
96
188
|
|
189
|
+
def Benelux.timelines
|
190
|
+
@@timelines
|
191
|
+
end
|
192
|
+
|
193
|
+
# Rename the method +meth+ in the object +obj+ and return
|
194
|
+
# the new alias.
|
195
|
+
#
|
196
|
+
# e.g.
|
197
|
+
#
|
198
|
+
# Benelux.renamed(SomeClass, :execute)
|
199
|
+
# # => __benelux_execute_2151884308_2165479316
|
200
|
+
#
|
97
201
|
def Benelux.rename_method(obj, meth)
|
98
202
|
## NOTE: This is commented out so we can include
|
99
203
|
## Benelux definitions before all classes are loaded.
|
@@ -107,20 +211,29 @@ module Benelux
|
|
107
211
|
end
|
108
212
|
meth_alias
|
109
213
|
end
|
110
|
-
|
214
|
+
|
215
|
+
# Creates a method definition (for an `eval` that) for a method
|
216
|
+
# named +meth+ which times a call to +meth_alias+.
|
111
217
|
def Benelux.generate_timer_str(meth_alias, meth)
|
112
218
|
%Q{
|
113
219
|
def #{meth}(*args, &block)
|
220
|
+
call_id = "" << self.object_id.abs.to_s << args.object_id.abs.to_s
|
114
221
|
# We only need to do these things once.
|
115
|
-
if self.
|
116
|
-
self.
|
222
|
+
if self.timeline.nil?
|
223
|
+
self.timeline = Benelux::Timeline.new
|
117
224
|
Benelux.store_thread_reference
|
118
225
|
end
|
119
|
-
|
120
|
-
|
226
|
+
mark_a = self.timeline.add_mark :'#{meth}_a'
|
227
|
+
mark_a.add_tag :call_id => call_id
|
228
|
+
tags = mark_a.tags
|
121
229
|
ret = #{meth_alias}(*args, &block)
|
122
|
-
|
123
|
-
|
230
|
+
rescue => ex
|
231
|
+
raise ex
|
232
|
+
ensure
|
233
|
+
mark_z = self.timeline.add_mark :'#{meth}_z'
|
234
|
+
mark_z.tags = tags # In case tags were added between these marks
|
235
|
+
range = self.timeline.add_range :'#{meth}', mark_a, mark_z
|
236
|
+
range.exception = ex if defined?(ex) && !ex.nil?
|
124
237
|
end
|
125
238
|
}
|
126
239
|
end
|
@@ -128,3 +241,6 @@ module Benelux
|
|
128
241
|
end
|
129
242
|
|
130
243
|
|
244
|
+
|
245
|
+
|
246
|
+
|
data/lib/benelux/mark.rb
CHANGED
@@ -1,37 +1,40 @@
|
|
1
1
|
module Benelux
|
2
2
|
class Mark < Time
|
3
|
+
include Benelux::TagHelpers
|
3
4
|
attr_accessor :name
|
4
|
-
|
5
|
-
attr_accessor :call_id
|
6
|
-
def self.now(n=nil,c=nil,t=nil)
|
5
|
+
def self.now(n=nil)
|
7
6
|
v = super()
|
8
|
-
v.
|
7
|
+
v.tags = Benelux::Tags.new
|
8
|
+
v.name = n
|
9
9
|
v
|
10
10
|
end
|
11
|
+
def track
|
12
|
+
@tags[:track]
|
13
|
+
end
|
14
|
+
def add_tags(tags=Benelux::Tags.new)
|
15
|
+
@tags.merge! tags
|
16
|
+
end
|
17
|
+
alias_method :add_tag, :add_tags
|
18
|
+
def remove_tags(*tags)
|
19
|
+
@tags.delete_if { |n,v| tags.member?(n) }
|
20
|
+
end
|
21
|
+
alias_method :remove_tag, :remove_tags
|
11
22
|
def inspect(reftime=nil)
|
12
|
-
val = reftime.nil? ? self
|
13
|
-
|
14
|
-
"#<%s:%s name=%s at=%f thread_id=%s call_id=%s>" % args
|
23
|
+
val = reftime.nil? ? self : (reftime - self)
|
24
|
+
"#<%s:%s at=%f name=%s %s>" % [self.class, hexoid, to_f, name, tags]
|
15
25
|
end
|
16
26
|
def to_s(reftime=nil)
|
17
|
-
val = reftime.nil? ? self
|
18
|
-
val.to_s
|
27
|
+
val = reftime.nil? ? self : (reftime - self)
|
28
|
+
val.to_f.to_s
|
29
|
+
end
|
30
|
+
def distance(time)
|
31
|
+
self - time
|
19
32
|
end
|
20
33
|
def ==(other)
|
21
34
|
return false unless other.respond_to? :call_id
|
22
35
|
self.name == other.name &&
|
23
|
-
self.
|
24
|
-
self.call_id == other.call_id &&
|
36
|
+
self.tags == other.tags &&
|
25
37
|
self.to_f == self.to_f
|
26
38
|
end
|
27
|
-
def same_timeline?(other)
|
28
|
-
return false unless other.respond_to? :thread_id
|
29
|
-
self.thread_id == other.thread_id
|
30
|
-
end
|
31
|
-
def same_call?(other)
|
32
|
-
return false unless other.respond_to? :call_id
|
33
|
-
self.thread_id == other.thread_id &&
|
34
|
-
self.call_id == other.call_id
|
35
|
-
end
|
36
39
|
end
|
37
40
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
|
2
|
+
module Benelux
|
3
|
+
class Range
|
4
|
+
include Benelux::TagHelpers
|
5
|
+
|
6
|
+
attr_accessor :name
|
7
|
+
attr_accessor :from
|
8
|
+
attr_accessor :to
|
9
|
+
attr_accessor :exception
|
10
|
+
def initialize(name,from,to)
|
11
|
+
@name, @from, @to = name, from, to
|
12
|
+
@tags = Benelux::Tags.new
|
13
|
+
end
|
14
|
+
def to_s
|
15
|
+
"%s:%.4f" % [name, duration]
|
16
|
+
end
|
17
|
+
def inspect
|
18
|
+
args = [self.class, hexoid, duration, from, to, name, tags]
|
19
|
+
"#<%s:%s duration=%0.4f from=%s to=%s name=%s %s>" % args
|
20
|
+
end
|
21
|
+
|
22
|
+
def track
|
23
|
+
@from.nil? ? :unknown : @from.track
|
24
|
+
end
|
25
|
+
def thread_id
|
26
|
+
@from.nil? ? :unknown : @from.thread_id
|
27
|
+
end
|
28
|
+
def call_id
|
29
|
+
@from.nil? ? :unknown : @from.call_id
|
30
|
+
end
|
31
|
+
def successful?
|
32
|
+
@exception.nil?
|
33
|
+
end
|
34
|
+
def failed?
|
35
|
+
!successful?
|
36
|
+
end
|
37
|
+
def duration
|
38
|
+
to - from
|
39
|
+
end
|
40
|
+
def <=>(other)
|
41
|
+
from <=> other.from
|
42
|
+
end
|
43
|
+
def <(other)
|
44
|
+
from < other
|
45
|
+
end
|
46
|
+
def >(other)
|
47
|
+
from > other
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
|
2
|
+
module Benelux
|
3
|
+
class Stats
|
4
|
+
attr_reader :names
|
5
|
+
def initialize(*names)
|
6
|
+
@names = []
|
7
|
+
add_keepers names
|
8
|
+
end
|
9
|
+
def get_keeper(name)
|
10
|
+
self.send name
|
11
|
+
end
|
12
|
+
# Each keeper
|
13
|
+
def each(&blk)
|
14
|
+
@names.each { |name| blk.call(get_keeper(name)) }
|
15
|
+
end
|
16
|
+
# Each keeper name, keeper
|
17
|
+
def each_pair(&blk)
|
18
|
+
@names.each { |name| blk.call(name, get_keeper(name)) }
|
19
|
+
end
|
20
|
+
def add_keepers(*args)
|
21
|
+
args.flatten.each do |meth|
|
22
|
+
next if has_keeper? meth
|
23
|
+
@names << meth
|
24
|
+
self.class.send :attr_reader, meth
|
25
|
+
instance_variable_set("@#{meth}", Benelux::Stats::Group.new(meth))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
alias_method :add_keeper, :add_keepers
|
29
|
+
def has_keeper?(name)
|
30
|
+
@names.member? name
|
31
|
+
end
|
32
|
+
def +(other)
|
33
|
+
if !other.is_a?(Benelux::Stats)
|
34
|
+
raise TypeError, "can't convert #{other.class} into Stats"
|
35
|
+
end
|
36
|
+
other.names.each do |name|
|
37
|
+
add_keeper name
|
38
|
+
a = self.send(name)
|
39
|
+
a += other.send(name)
|
40
|
+
a
|
41
|
+
end
|
42
|
+
self
|
43
|
+
end
|
44
|
+
|
45
|
+
class Group < Array
|
46
|
+
attr_reader :name
|
47
|
+
def initialize(name)
|
48
|
+
@name = name
|
49
|
+
end
|
50
|
+
|
51
|
+
def +(other)
|
52
|
+
unless @name == other.name
|
53
|
+
raise BeneluxError, "Cannot add #{other.name} to #{@name}"
|
54
|
+
end
|
55
|
+
other.each do |newcalc|
|
56
|
+
calcs = self.select { |calc| calc.tags == newcalc.tags }
|
57
|
+
self << newcalc and next if calcs.empty?
|
58
|
+
# This should only ever contain one b/c we should
|
59
|
+
# not have several calculators with the same tags.
|
60
|
+
calcs.each do |calc|
|
61
|
+
calc += newcalc
|
62
|
+
end
|
63
|
+
end
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
def sample(s, tags={})
|
68
|
+
raise BeneluxError, "tags must be a Hash" unless tags.kind_of?(Hash)
|
69
|
+
calcs = self.select { |c| c.tags == tags }
|
70
|
+
if calcs.empty?
|
71
|
+
(c = Calculator.new).add_tags tags
|
72
|
+
self << c
|
73
|
+
calcs = [c]
|
74
|
+
end
|
75
|
+
calcs.each { |c| c.sample(s) }
|
76
|
+
nil
|
77
|
+
end
|
78
|
+
|
79
|
+
def mean() merge.mean end
|
80
|
+
def min() merge.min end
|
81
|
+
def max() merge.max end
|
82
|
+
def sd() merge.sd end
|
83
|
+
def n() merge.n end
|
84
|
+
|
85
|
+
def merge(*tags)
|
86
|
+
tags = Benelux::TagHelpers.normalize tags
|
87
|
+
mc = Calculator.new
|
88
|
+
all = tags.empty? ? self : self.filter(tags)
|
89
|
+
all.each { |calc|
|
90
|
+
mc.samples calc
|
91
|
+
mc.add_tags calc.tags
|
92
|
+
}
|
93
|
+
mc
|
94
|
+
end
|
95
|
+
|
96
|
+
def [](*tags)
|
97
|
+
tags = Benelux::TagHelpers.normalize tags
|
98
|
+
g = Benelux::Stats::Group.new @name
|
99
|
+
g << self.select { |c| c.tags >= tags }
|
100
|
+
g.flatten!(1) # only 1 level deep
|
101
|
+
g
|
102
|
+
end
|
103
|
+
alias_method :filter, :[]
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
# Based on Mongrel::Stats, Copyright (c) 2005 Zed A. Shaw
|
108
|
+
class Calculator < Array
|
109
|
+
include Benelux::TagHelpers
|
110
|
+
|
111
|
+
attr_reader :sum, :sumsq, :n, :min, :max
|
112
|
+
|
113
|
+
def initialize
|
114
|
+
reset
|
115
|
+
end
|
116
|
+
|
117
|
+
def +(other)
|
118
|
+
super(other)
|
119
|
+
self.recalculate
|
120
|
+
self
|
121
|
+
end
|
122
|
+
|
123
|
+
# Resets the internal counters so you can start sampling again.
|
124
|
+
def reset
|
125
|
+
self.clear
|
126
|
+
@n, @sum, @sumsq = 0.0, 0.0, 0.0
|
127
|
+
@last_time = 0.0
|
128
|
+
@min, @max = 0.0, 0.0
|
129
|
+
end
|
130
|
+
|
131
|
+
def samples(*args)
|
132
|
+
args.flatten.each { |s| sample(s) }
|
133
|
+
end
|
134
|
+
|
135
|
+
# Adds a sampling to the calculations.
|
136
|
+
def sample(s)
|
137
|
+
self << s
|
138
|
+
update s
|
139
|
+
end
|
140
|
+
|
141
|
+
def update(s)
|
142
|
+
@sum += s
|
143
|
+
@sumsq += s * s
|
144
|
+
if @n == 0
|
145
|
+
@min = @max = s
|
146
|
+
else
|
147
|
+
@min = s if @min > s
|
148
|
+
@max = s if @max < s
|
149
|
+
end
|
150
|
+
@n+=1
|
151
|
+
end
|
152
|
+
|
153
|
+
# Dump this Stats object with an optional additional message.
|
154
|
+
def dump(msg = "", out=STDERR)
|
155
|
+
out.puts "#{msg}: #{self.inspect}"
|
156
|
+
end
|
157
|
+
|
158
|
+
# Returns a common display (used by dump)
|
159
|
+
def inspect
|
160
|
+
v = [mean, @n, @sum, @sumsq, sd, @min, @max]
|
161
|
+
t = %q'%8d(N) %10.4f(SUM) %8.4f(SUMSQ) %8.4f(SD) %8.4f(MIN) %8.4f(MAX)'
|
162
|
+
('%0.4f: ' << t) % v
|
163
|
+
end
|
164
|
+
|
165
|
+
def to_s; mean.to_s; end
|
166
|
+
def to_f; mean.to_f; end
|
167
|
+
def to_i; mean.to_i; end
|
168
|
+
|
169
|
+
# Calculates and returns the mean for the data passed so far.
|
170
|
+
def mean; return 0.0 unless @n > 0; @sum / @n; end
|
171
|
+
|
172
|
+
# Calculates the standard deviation of the data so far.
|
173
|
+
def sd
|
174
|
+
return 0.0 if @n <= 1
|
175
|
+
# (sqrt( ((s).sumsq - ( (s).sum * (s).sum / (s).n)) / ((s).n-1) ))
|
176
|
+
begin
|
177
|
+
return Math.sqrt( (@sumsq - ( @sum * @sum / @n)) / (@n-1) )
|
178
|
+
rescue Errno::EDOM
|
179
|
+
return 0.0
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def recalculate
|
184
|
+
samples = self.clone
|
185
|
+
reset
|
186
|
+
samples.each { |s| sample(s) }
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
end
|
193
|
+
end
|
data/lib/benelux/tags.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Benelux
|
4
|
+
|
5
|
+
# Helper methods for objects with a @tags instance var
|
6
|
+
#
|
7
|
+
# e.g.
|
8
|
+
#
|
9
|
+
# class Something
|
10
|
+
# include Benelux::TagHelpers
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
module TagHelpers
|
14
|
+
attr_accessor :tags
|
15
|
+
def add_tags(tags)
|
16
|
+
@tags ||= Benelux::Tags.new
|
17
|
+
@tags.merge! tags
|
18
|
+
end
|
19
|
+
alias_method :add_tag, :add_tags
|
20
|
+
def remove_tags(*tags)
|
21
|
+
tags.flatten!
|
22
|
+
@tags ||= Benelux::Tags.new
|
23
|
+
@tags.delete_if { |n,v| tags.member?(n) }
|
24
|
+
end
|
25
|
+
alias_method :remove_tag, :remove_tags
|
26
|
+
def tag_values(*tags)
|
27
|
+
tags.flatten!
|
28
|
+
@tags ||= Benelux::Tags.new
|
29
|
+
ret = @tags.collect { |n,v|
|
30
|
+
p [:n, v]
|
31
|
+
v if tags.empty? || tags.member?(n)
|
32
|
+
}.compact
|
33
|
+
ret
|
34
|
+
end
|
35
|
+
def self.normalize(tags={})
|
36
|
+
tags = tags.first if tags.kind_of?(Array) && tags.first.kind_of?(Hash)
|
37
|
+
tags = [tags].flatten unless tags.kind_of?(Hash)
|
38
|
+
tags
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# An example of filtering an Array of tagged objects based
|
43
|
+
# on a provided Hash of tags or Array of tag values. +obj+
|
44
|
+
# in this case would be an object that includes TagHelpers.
|
45
|
+
#
|
46
|
+
# class Something
|
47
|
+
# def [](tags={})
|
48
|
+
# tags = [tags].flatten unless tags.is_a?(Hash)
|
49
|
+
# self.select do |obj|
|
50
|
+
# obj.tags >= tags
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
class Tags < ::Hash
|
56
|
+
|
57
|
+
def to_s
|
58
|
+
tagstr = []
|
59
|
+
self.each_pair do |n,v|
|
60
|
+
tagstr << "%s=%s" % [n,v]
|
61
|
+
end
|
62
|
+
tagstr.join ' '
|
63
|
+
end
|
64
|
+
|
65
|
+
def inspect
|
66
|
+
to_s
|
67
|
+
end
|
68
|
+
|
69
|
+
def ==(*other)
|
70
|
+
other = Benelux::TagHelpers.normalize other
|
71
|
+
if other.is_a?(Array)
|
72
|
+
(self.values & other).sort == other.sort
|
73
|
+
else
|
74
|
+
super(other)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Comparison between other Hash and Array objects.
|
79
|
+
#
|
80
|
+
# e.g.
|
81
|
+
#
|
82
|
+
# a = {:a => 1, :b => 2}
|
83
|
+
# a > {:a => 1, :b => 2, :c => 3} # => false
|
84
|
+
# a > {:a => 1} # => true
|
85
|
+
# a < {:a => 1, :b => 2, :c => 3} # => true
|
86
|
+
# a >= [2, 1] # => true
|
87
|
+
# a > [2, 1] # => false
|
88
|
+
#
|
89
|
+
def <=>(*other)
|
90
|
+
other = Benelux::TagHelpers.normalize other
|
91
|
+
return 0 if self == other
|
92
|
+
if other.is_a?(Array)
|
93
|
+
return -1 unless (self.values & other).size >= other.size
|
94
|
+
else
|
95
|
+
return -1 unless (self.keys & other.keys).size >= other.keys.size
|
96
|
+
other.each_pair { |n,v|
|
97
|
+
return -1 unless self.has_key?(n) && self[n] == v
|
98
|
+
}
|
99
|
+
end
|
100
|
+
1
|
101
|
+
end
|
102
|
+
|
103
|
+
def >(other) (self <=> other) > 0 end
|
104
|
+
def <(other) (self <=> other) < 0 end
|
105
|
+
|
106
|
+
def <=(other) (self <=> other) <= 0 end
|
107
|
+
def >=(other) (self <=> other) >= 0 end
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
data/lib/benelux/timeline.rb
CHANGED
@@ -1,10 +1,49 @@
|
|
1
1
|
|
2
2
|
module Benelux
|
3
3
|
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
4
|
+
# |------+----+--+----+----|
|
5
|
+
# |
|
6
|
+
# 0.02
|
7
|
+
#
|
8
|
+
# Usage examples::
|
9
|
+
#
|
10
|
+
# Benelux.timeline['9dbd521de4dfd6257135649d78a9c0aa2dd58cfe'].each do |mark|
|
11
|
+
# p [mark.track, mark.name, mark.tags[:usecase], mark.tags[:call_id]]
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# Benelux.timeline.ranges(:do_request).each do |range|
|
15
|
+
# puts "Client%s: %s: %s: %f" % [range.track, range.thread_id, range.name, range.duration]
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# regions = Benelux.timeline(track_id).regions(:execute)
|
19
|
+
#
|
7
20
|
class Timeline < Array
|
21
|
+
attr_accessor :ranges
|
22
|
+
attr_accessor :stats
|
23
|
+
attr_accessor :default_tags
|
24
|
+
attr_reader :caller
|
25
|
+
def initialize(*args)
|
26
|
+
@caller = Kernel.caller
|
27
|
+
@ranges, @default_tags = [], Benelux::Tags.new
|
28
|
+
@stats = Benelux::Stats.new
|
29
|
+
add_default_tag :thread_id => Thread.current.object_id.abs
|
30
|
+
super
|
31
|
+
end
|
32
|
+
def add_default_tags(tags=Benelux::Tags.new)
|
33
|
+
@default_tags.merge! tags
|
34
|
+
end
|
35
|
+
alias_method :add_default_tag, :add_default_tags
|
36
|
+
def remove_default_tags(*tags)
|
37
|
+
@default_tags.delete_if { |n,v| tags.member?(n) }
|
38
|
+
end
|
39
|
+
alias_method :add_default_tag, :add_default_tags
|
40
|
+
def track
|
41
|
+
@default_tags[:track]
|
42
|
+
end
|
43
|
+
|
44
|
+
def duration
|
45
|
+
self.last - self.first
|
46
|
+
end
|
8
47
|
|
9
48
|
def each(*args, &blk)
|
10
49
|
if args.empty?
|
@@ -14,58 +53,105 @@ module Benelux
|
|
14
53
|
end
|
15
54
|
end
|
16
55
|
|
17
|
-
##def between(*names)
|
18
|
-
## name_s, name_e = *names.collect { |n| Benelux.name n }
|
19
|
-
## time_s, time_e = at(name_s), at(name_e)
|
20
|
-
## time_e.first.to_f - time_s.first.to_f
|
21
|
-
##end
|
22
|
-
##def duration(*names)
|
23
|
-
## name = Benelux.name *names
|
24
|
-
## name_s, name_e = "#{name}_a", "#{name}_z"
|
25
|
-
## between(name_s, name_e)
|
26
|
-
##end
|
27
|
-
|
28
|
-
#
|
29
|
-
# obj.region(:execute) =>
|
30
|
-
# [[:execute_a, :execute_z], [:execute_a, :execute_z]]
|
31
|
-
#
|
32
|
-
def regions(*names)
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
56
|
#
|
37
57
|
# obj.marks(:execute_a, :execute_z, :do_request_a) =>
|
38
58
|
# [:execute_a, :do_request_a, :do_request_a, :execute_z]
|
39
59
|
#
|
40
60
|
def marks(*names)
|
61
|
+
return self if names.empty?
|
41
62
|
names = names.flatten.collect { |n| n.to_s }
|
42
|
-
self.
|
63
|
+
self.select do |mark|
|
43
64
|
names.member? mark.name.to_s
|
44
65
|
end
|
45
66
|
end
|
46
67
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
68
|
+
def [](tags={})
|
69
|
+
tags = Benelux::TagHelpers.normalize tags
|
70
|
+
marks = self.select do |mark|
|
71
|
+
mark.tags >= tags
|
72
|
+
end
|
73
|
+
tl = Benelux::Timeline.new marks
|
74
|
+
tl.ranges = @ranges.select do |region|
|
75
|
+
region.tags >= tags
|
76
|
+
end
|
77
|
+
stats = Benelux::Stats.new
|
78
|
+
@stats.each do |stat|
|
79
|
+
next unless stat.tags >= tags
|
80
|
+
stats += stat
|
81
|
+
end
|
82
|
+
tl.stats = stats
|
83
|
+
tl
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
# obj.ranges(:do_request) =>
|
88
|
+
# [[:do_request_a, :do_request_z], [:do_request_a, ...]]
|
89
|
+
#
|
90
|
+
def ranges(name=nil, tags=Benelux::Tags.new)
|
91
|
+
return @ranges if name.nil?
|
92
|
+
@ranges.select do |range|
|
93
|
+
ret = name.to_s == range.name.to_s &&
|
94
|
+
(tags.nil? || range.tags >= tags)
|
95
|
+
ret
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
#
|
100
|
+
# obj.ranges(:do_request) =>
|
101
|
+
# [[:do_request_a, :get_body, :do_request_z], [:do_request_a, ...]]
|
102
|
+
#
|
103
|
+
def regions(name=nil, tags=Benelux::Tags.new)
|
104
|
+
return self if name.nil?
|
105
|
+
self.ranges(name, tags).collect do |base_range|
|
106
|
+
marks = self.sort.select do |mark|
|
107
|
+
mark >= base_range.from &&
|
108
|
+
mark <= base_range.to &&
|
109
|
+
mark.tags >= base_range.tags
|
110
|
+
end
|
111
|
+
ranges = self.ranges.select do |range|
|
112
|
+
range.from >= base_range.from &&
|
113
|
+
range.to <= base_range.to &&
|
114
|
+
range.tags >= base_range.tags
|
115
|
+
end
|
116
|
+
tl = Benelux::Timeline.new(marks)
|
117
|
+
tl.ranges = ranges.sort
|
118
|
+
tl
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def clear
|
123
|
+
@ranges.clear
|
124
|
+
super
|
50
125
|
end
|
51
126
|
|
52
|
-
def add_mark(
|
53
|
-
|
54
|
-
mark
|
127
|
+
def add_mark(name)
|
128
|
+
mark = Benelux::Mark.now(name)
|
129
|
+
mark.add_tags Benelux.thread_timeline.default_tags
|
130
|
+
mark.add_tags self.default_tags
|
55
131
|
Benelux.thread_timeline << mark
|
56
132
|
self << mark
|
133
|
+
mark
|
57
134
|
end
|
58
|
-
|
59
|
-
def
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
135
|
+
|
136
|
+
def add_range(name, from, to)
|
137
|
+
range = Benelux::Range.new(name, from, to)
|
138
|
+
range.add_tags Benelux.thread_timeline.default_tags
|
139
|
+
range.add_tags self.default_tags
|
140
|
+
@stats.add_keeper(name)
|
141
|
+
@stats.send(name).sample(range.duration, range.tags)
|
142
|
+
@ranges << range
|
143
|
+
Benelux.thread_timeline.ranges << range
|
144
|
+
Benelux.thread_timeline.stats.add_keeper(name)
|
145
|
+
Benelux.thread_timeline.stats.send(name).sample(range.duration, range.tags)
|
146
|
+
range
|
65
147
|
end
|
66
|
-
|
148
|
+
|
67
149
|
def to_line
|
68
150
|
marks = self.sort
|
151
|
+
end
|
152
|
+
|
153
|
+
def to_line2
|
154
|
+
marks = self.sort
|
69
155
|
str, prev = [], marks.first
|
70
156
|
marks.each do |mark|
|
71
157
|
str << "%s(%s):%.4f" % [mark.name, mark.thread_id, mark.to_s(prev)]
|
@@ -75,7 +161,10 @@ module Benelux
|
|
75
161
|
end
|
76
162
|
def +(other)
|
77
163
|
self << other
|
78
|
-
self.
|
164
|
+
self.ranges += other.ranges
|
165
|
+
self.stats += other.stats
|
166
|
+
self.flatten!
|
167
|
+
self
|
79
168
|
end
|
80
169
|
# Needs to compare thread id and call id.
|
81
170
|
#def <=>(other)
|
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
group "Benelux"
|
3
|
+
|
4
|
+
library :benelux, 'lib'
|
5
|
+
tryouts "Calculator" do
|
6
|
+
|
7
|
+
dream :class, Benelux::Stats::Calculator
|
8
|
+
dream :n, 10
|
9
|
+
drill "can keep stats" do
|
10
|
+
keeper = Benelux::Stats::Calculator.new
|
11
|
+
10.times { keeper.sample(rand) }
|
12
|
+
keeper
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
tryouts "Stats" do
|
18
|
+
set :stat_names, [:execute, :request, :first_byte]
|
19
|
+
|
20
|
+
dream stat_names
|
21
|
+
drill "knows stats names" do
|
22
|
+
stats = Benelux::Stats.new(stat_names)
|
23
|
+
stats.names
|
24
|
+
end
|
25
|
+
|
26
|
+
drill "can keep multiple stats", true do
|
27
|
+
stats = Benelux::Stats.new(stat_names)
|
28
|
+
stats.execute.sample(rand)
|
29
|
+
stats.request.sample(rand*-1)
|
30
|
+
stats.execute != stats.request
|
31
|
+
end
|
32
|
+
|
33
|
+
dream [true, true, true]
|
34
|
+
drill "can keep stats with tags" do
|
35
|
+
stats = Benelux::Stats.new(stat_names)
|
36
|
+
3.times { |i|
|
37
|
+
stats.execute.sample(rand, :usecase => '11')
|
38
|
+
stats.execute.sample(rand, :usecase => '11', :request => '22')
|
39
|
+
stats.execute.sample(rand, :request => '22')
|
40
|
+
}
|
41
|
+
stash :execute_stats, stats.execute
|
42
|
+
[
|
43
|
+
stats.execute['11'] == stats.execute[:usecase => '11'],
|
44
|
+
stats.execute['22'] == stats.execute[:request => '22'],
|
45
|
+
stats.execute['22','11'] == stats.execute[:usecase => '11', :request => '22']
|
46
|
+
]
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
|
2
|
+
group "Benelux"
|
3
|
+
|
4
|
+
library :benelux, 'lib'
|
5
|
+
tryouts "Tags" do
|
6
|
+
set :base, Benelux::Tags[:a => 1, :b => 2]
|
7
|
+
|
8
|
+
drill "Can equal a Hash with the same keys/values", true do
|
9
|
+
base == {:a => 1, :b => 2}
|
10
|
+
end
|
11
|
+
|
12
|
+
drill "Implements a comparison operator", true do
|
13
|
+
base.respond_to? :'<=>'
|
14
|
+
end
|
15
|
+
|
16
|
+
drill "Comparison operator returns 0 for same values", 0 do
|
17
|
+
base <=> {:a => 1, :b => 2}
|
18
|
+
end
|
19
|
+
|
20
|
+
drill "Comparison operator returns 1 when it's a superset of other", 1 do
|
21
|
+
base <=> {:a => 1}
|
22
|
+
end
|
23
|
+
|
24
|
+
drill "Comparison operator returns -1 when it's a subset of other", -1 do
|
25
|
+
base <=> {:a => 1, :b => 2, :c => 3}
|
26
|
+
end
|
27
|
+
|
28
|
+
drill "> returns false when compared to a hash with more key value pairs", false do
|
29
|
+
base > {:a => 1, :b => 2, :c => 3}
|
30
|
+
end
|
31
|
+
|
32
|
+
drill "> returns true when compared to a hash with fewer key value pairs", true do
|
33
|
+
base > {:b => 2}
|
34
|
+
end
|
35
|
+
|
36
|
+
drill "< returns true when compared to a hash with more key value pairs", true do
|
37
|
+
base < {:a => 1, :b => 2, :c => 3}
|
38
|
+
end
|
39
|
+
|
40
|
+
drill "< returns false when compared to a hash with fewer key value pairs", false do
|
41
|
+
base < {:b => 2}
|
42
|
+
end
|
43
|
+
|
44
|
+
drill "< returns false when compared to a hash with same values", false do
|
45
|
+
base < {:a => 1, :b => 2}
|
46
|
+
end
|
47
|
+
|
48
|
+
drill "<= returns true when compared to a hash with same values", true do
|
49
|
+
base <= {:b => 2, :a => 1}
|
50
|
+
end
|
51
|
+
|
52
|
+
drill "< returns false when compared to an array with same values", false do
|
53
|
+
base < [1, 2]
|
54
|
+
end
|
55
|
+
|
56
|
+
drill "<= returns true when compared to an array with same values", true do
|
57
|
+
base <= [2, 1]
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -13,13 +13,13 @@ tryouts "Basics" do
|
|
13
13
|
|
14
14
|
drill "Add timers to existing objects", true do
|
15
15
|
Benelux.add_timer Sleeper, :do_something
|
16
|
-
Sleeper.new.respond_to? :
|
16
|
+
Sleeper.new.respond_to? :timeline
|
17
17
|
end
|
18
18
|
|
19
19
|
dream :class, Hash
|
20
20
|
dream { Hash[ Sleeper => [:do_something] ] }
|
21
21
|
drill "Benelux keeps track of timed objects" do
|
22
|
-
Benelux.
|
22
|
+
Benelux.timed_methods
|
23
23
|
end
|
24
24
|
|
25
25
|
dream [:do_something]
|
@@ -32,7 +32,7 @@ tryouts "Basics" do
|
|
32
32
|
drill "Creates a timeline" do
|
33
33
|
sleeper = Sleeper.new
|
34
34
|
5.times { sleeper.do_something }
|
35
|
-
sleeper.
|
35
|
+
sleeper.timeline
|
36
36
|
end
|
37
37
|
|
38
38
|
dream :size, 4
|
@@ -41,7 +41,7 @@ tryouts "Basics" do
|
|
41
41
|
Thread.new do
|
42
42
|
2.times { sleeper.do_something }
|
43
43
|
end.join
|
44
|
-
sleeper.
|
44
|
+
sleeper.timeline
|
45
45
|
end
|
46
46
|
|
47
47
|
dream :class, Benelux::Timeline
|
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
group "Benelux"
|
3
|
+
|
4
|
+
library :benelux, 'lib'
|
5
|
+
tryouts "Timelines" do
|
6
|
+
set :tl, Benelux::Timeline.new
|
7
|
+
|
8
|
+
dream :class, Benelux::Timeline
|
9
|
+
dream :size, 3
|
10
|
+
drill "create timeline with marks" do
|
11
|
+
tl.add_default_tags :a => :frog
|
12
|
+
tl.add_mark(:one) and sleep rand
|
13
|
+
tl.add_default_tags :b => :rest
|
14
|
+
tl.add_mark(:two) and sleep rand
|
15
|
+
tl.add_default_tags :c => :tilt
|
16
|
+
tl.add_mark(:three) and sleep rand
|
17
|
+
tl.marks
|
18
|
+
end
|
19
|
+
|
20
|
+
dream :size, 2
|
21
|
+
drill "select marks based on tags" do
|
22
|
+
tl[:frog][:b => :rest]
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
tryouts "Alias method speed", :benchmark do
|
4
|
+
set :runcount, 1_000
|
5
|
+
|
6
|
+
setup do
|
7
|
+
module A;
|
8
|
+
extend self
|
9
|
+
def meth1; end
|
10
|
+
def meth2; end
|
11
|
+
alias_method :meth2_orig, :meth2
|
12
|
+
def meth2; end
|
13
|
+
def meth2_with_call; meth2_orig; end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
[10, 100].each do |mult|
|
18
|
+
count = runcount * mult
|
19
|
+
|
20
|
+
drill "Natural method (#{count})", count do
|
21
|
+
A.meth1
|
22
|
+
end
|
23
|
+
|
24
|
+
drill "Aliased method (#{count})", count do
|
25
|
+
A.meth2
|
26
|
+
end
|
27
|
+
|
28
|
+
drill "Aliased method w/ call (#{count})", count do
|
29
|
+
A.meth2_with_call
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
group "Benelux Concept Proofs"
|
2
|
+
|
3
|
+
xtryouts "Time benchmarks", :benchmark do
|
4
|
+
set :runcount, 100000
|
5
|
+
|
6
|
+
drill "Create Array", 1 do
|
7
|
+
@@timers = []
|
8
|
+
end
|
9
|
+
|
10
|
+
drill "Time.now overhead", 5 do
|
11
|
+
runcount.times { Time.now.to_f }
|
12
|
+
end
|
13
|
+
|
14
|
+
drill "[] << Time.now overhead", 5 do
|
15
|
+
runcount.times { @@timers << Time.now.to_f }
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'date'
|
21
|
+
tryouts "Time proofs", :api do
|
22
|
+
set :runcount, 100000
|
23
|
+
|
24
|
+
drill "All calls to Time.now.to_f are unique (will fail)", 0 do
|
25
|
+
timers = []
|
26
|
+
runcount.times { timers << Time.now.to_f; sleep 0.00000001 }
|
27
|
+
timers.size - timers.uniq.size
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: benelux
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Delano Mandelbaum
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-10-01 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -41,8 +41,16 @@ files:
|
|
41
41
|
- lib/benelux.rb
|
42
42
|
- lib/benelux/mark.rb
|
43
43
|
- lib/benelux/mixins/thread.rb
|
44
|
+
- lib/benelux/range.rb
|
45
|
+
- lib/benelux/stats.rb
|
46
|
+
- lib/benelux/tags.rb
|
44
47
|
- lib/benelux/timeline.rb
|
45
|
-
- tryouts/
|
48
|
+
- tryouts/10_stats_tryouts.rb
|
49
|
+
- tryouts/11_tags_tryouts.rb
|
50
|
+
- tryouts/20_class_methods_tryouts.rb
|
51
|
+
- tryouts/30_timeline_tryouts.rb
|
52
|
+
- tryouts/proofs/alias_performance.rb
|
53
|
+
- tryouts/proofs/timer_threading.rb
|
46
54
|
has_rdoc: true
|
47
55
|
homepage: http://github.com/delano/benelux
|
48
56
|
licenses: []
|