benelux 0.2.0.001 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|