benchmarker 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGES.md +9 -0
- data/MIT-LICENSE +20 -0
- data/README.md +26 -0
- data/Rakefile +107 -0
- data/benchmarker.gemspec +20 -34
- data/lib/benchmarker.rb +1041 -0
- data/test/benchmarker_test.rb +1532 -560
- metadata +53 -79
- data/CHANGES.txt +0 -6
- data/examples/bench_loop.rb +0 -51
- data/examples/bench_require.rb +0 -34
- data/test/oktest.rb +0 -825
data/test/benchmarker_test.rb
CHANGED
@@ -1,694 +1,1666 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
1
4
|
###
|
2
|
-
### $Release:
|
3
|
-
### $Copyright: copyright(c) 2010-
|
4
|
-
### $License:
|
5
|
+
### $Release: 1.0.0 $
|
6
|
+
### $Copyright: copyright(c) 2010-2021 kuwata-lab.com all rights reserved $
|
7
|
+
### $License: MIT License $
|
5
8
|
###
|
6
9
|
|
7
|
-
|
8
|
-
$:.unshift File.class_eval { expand_path(join(dirname(__FILE__), '../lib')) }
|
10
|
+
$LOAD_PATH.unshift File.class_eval { join(dirname(dirname(__FILE__)), 'lib') }
|
9
11
|
|
10
12
|
require 'oktest'
|
13
|
+
|
14
|
+
BENCHMARKER_IGNORE_CMDOPTS = true
|
11
15
|
require 'benchmarker'
|
12
16
|
|
13
17
|
|
14
|
-
|
15
|
-
|
18
|
+
Oktest.scope do
|
19
|
+
|
16
20
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
+
+ topic(Benchmarker) do
|
22
|
+
|
23
|
+
+ topic('.new()') do
|
24
|
+
- spec("[!2zh7w] creates new Benchmark object wit options..") do
|
25
|
+
bm = Benchmarker.new()
|
26
|
+
ok {bm}.is_a?(Benchmarker::Benchmark)
|
27
|
+
ok {bm.width} == 30
|
28
|
+
ok {bm.loop} == 1
|
29
|
+
ok {bm.iter} == 1
|
30
|
+
ok {bm.extra} == 0
|
31
|
+
ok {bm.inverse} == false
|
32
|
+
ok {bm.outfile} == nil
|
33
|
+
#
|
34
|
+
bm = Benchmarker.new(width: 25, loop: 100, iter: 3, extra: 2, inverse: true, outfile: "tmp.js")
|
35
|
+
ok {bm}.is_a?(Benchmarker::Benchmark)
|
36
|
+
ok {bm.width} == 25
|
37
|
+
ok {bm.loop} == 100
|
38
|
+
ok {bm.iter} == 3
|
39
|
+
ok {bm.extra} == 2
|
40
|
+
ok {bm.inverse} == true
|
41
|
+
ok {bm.outfile} == "tmp.js"
|
42
|
+
end
|
43
|
+
- spec("[!s7y6x] overwrites existing options by command-line options.") do
|
44
|
+
kws = {width: 15, loop: 1000, iter: 20, extra: 3, inverse: true, outfile: "tmp2.js"}
|
45
|
+
bm = dummy_values(Benchmarker::OPTIONS, **kws) {
|
46
|
+
Benchmarker.new()
|
47
|
+
}
|
48
|
+
ok {bm}.is_a?(Benchmarker::Benchmark)
|
49
|
+
ok {bm.width} == 15
|
50
|
+
ok {bm.loop} == 1000
|
51
|
+
ok {bm.iter} == 20
|
52
|
+
ok {bm.extra} == 3
|
53
|
+
ok {bm.inverse} == true
|
54
|
+
ok {bm.outfile} == "tmp2.js"
|
55
|
+
end
|
21
56
|
end
|
22
|
-
end
|
23
57
|
|
24
|
-
|
25
|
-
spec
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
58
|
+
+ topic('.scope()') do
|
59
|
+
- spec("[!4f695] creates Benchmark object, define tasks, and run them.") do
|
60
|
+
this = self
|
61
|
+
sout, serr = capture_sio do
|
62
|
+
Benchmarker.scope() do
|
63
|
+
this.ok {self}.is_a?(Benchmarker::Scope)
|
64
|
+
task "1+1" do
|
65
|
+
1+1
|
66
|
+
end
|
67
|
+
task "1-1" do
|
68
|
+
1-1
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
ok {serr} == ""
|
73
|
+
ok {sout} =~ /^## benchmarker: *release \d+.\d+.\d+$/
|
74
|
+
ok {sout} =~ /^## Ranking/
|
75
|
+
ok {sout} =~ /^1\+1 +0\./
|
76
|
+
ok {sout} =~ /^1\-1 +0\./
|
77
|
+
ok {sout} =~ /^## Matrix/
|
78
|
+
end
|
40
79
|
end
|
41
|
-
end
|
42
80
|
|
43
|
-
end
|
81
|
+
end
|
44
82
|
|
45
83
|
|
46
|
-
|
47
|
-
include Oktest::TestCase
|
84
|
+
+ topic(Benchmarker::Benchmark) do
|
48
85
|
|
49
|
-
|
50
|
-
|
51
|
-
runner = Benchmarker::RUNNER.new(:loop=>10, :cycle=>20, :extra=>30)
|
52
|
-
ok {runner.instance_variable_get('@loop')} == 10
|
53
|
-
ok {runner.instance_variable_get('@cycle')} == 20
|
54
|
-
ok {runner.instance_variable_get('@extra')} == 30
|
86
|
+
fixture :bm do
|
87
|
+
Benchmarker::Benchmark.new
|
55
88
|
end
|
56
|
-
end
|
57
89
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
spec "prints section title if not printed yet." do
|
68
|
-
ok {sout} =~ /\A\n## {28} user sys total real\n.*\n/
|
69
|
-
ok {serr} == ""
|
70
|
-
end
|
71
|
-
spec "creates task objet and returns it." do
|
72
|
-
ok {ret}.is_a?(Benchmarker::TASK)
|
73
|
-
end
|
74
|
-
spec "saves created task object unless :skip optin is not specified." do
|
75
|
-
task = ret
|
76
|
-
ok {runner.tasks} == [task]
|
77
|
-
end
|
78
|
-
spec "runs task when :skip option is not specified." do
|
79
|
-
ok {called} == true
|
80
|
-
ok {sout} =~ /\A\n.*\nlabel1 0\.\d+ 0\.\d+ 0\.\d+ 0\.\d+\n/
|
81
|
-
end
|
82
|
-
spec "skip block and prints message when :skip option is specified." do
|
83
|
-
ok {sout} =~ /^label2 *\# not installed\.\n/
|
84
|
-
end
|
85
|
-
spec "subtracts times of empty task if exists." do
|
86
|
-
empty_task = runner.empty_task { nil }
|
87
|
-
empty_task.user = 10.0
|
88
|
-
empty_task.sys = 5.0
|
89
|
-
empty_task.total = 15.0
|
90
|
-
empty_task.real = 20.0
|
91
|
-
t = runner.task("label2") { x = 1+1 }
|
92
|
-
ok {t.user }.in_delta?(-10.0, 0.1)
|
93
|
-
ok {t.sys }.in_delta?(- 5.0, 0.1)
|
94
|
-
ok {t.total}.in_delta?(-15.0, 0.1)
|
95
|
-
ok {t.real }.in_delta?(-20.0, 0.1)
|
90
|
+
+ topic('#initialize()') do
|
91
|
+
- spec("[!0mz0f] error when filter string is invalid format.") do
|
92
|
+
pr = proc { Benchmarker::Benchmark.new(filter: 'foobar') }
|
93
|
+
ok {pr}.raise?(ArgumentError, "foobar: invalid filter.")
|
94
|
+
end
|
95
|
+
- spec("[!xo7bq] error when filter operator is invalid.") do
|
96
|
+
pr = proc { Benchmarker::Benchmark.new(filter: 'task==foobar') }
|
97
|
+
ok {pr}.raise?(ArgumentError, "task==foobar: expected operator is '=' or '!='.")
|
98
|
+
end
|
96
99
|
end
|
97
|
-
end
|
98
100
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
101
|
+
+ topic('#clear()') do
|
102
|
+
- spec("[!phqdn] clears benchmark result and JSON data.") do |bm|
|
103
|
+
bm.scope do
|
104
|
+
task "foo" do nil end
|
105
|
+
task "bar" do nil end
|
106
|
+
end
|
107
|
+
capture_sio { bm.run() }
|
108
|
+
result_foo = bm.instance_eval{@entries[0][1]}
|
109
|
+
result_bar = bm.instance_eval{@entries[1][1]}
|
110
|
+
ok {result_foo.length} == 1
|
111
|
+
ok {result_bar.length} == 1
|
112
|
+
#
|
113
|
+
bm.clear()
|
114
|
+
ok {result_foo.length} == 0
|
115
|
+
ok {result_bar.length} == 0
|
105
116
|
end
|
106
|
-
ok {task}.is_a?(Benchmarker::TASK)
|
107
|
-
ok {task.label} == "(Empty)"
|
108
|
-
end
|
109
|
-
spec "prints section title if not printed yet." do
|
110
|
-
ok {sout} =~ /^## +user +sys +total +real\n/
|
111
|
-
end
|
112
|
-
spec "saves empty task object." do
|
113
|
-
ok {runner.instance_variable_get('@_empty_task')} == task
|
114
117
|
end
|
115
|
-
|
116
|
-
|
118
|
+
|
119
|
+
+ topic('#scope()') do
|
120
|
+
- spec("[!wrjy0] creates wrapper object and yields block with it as self.") do |bm|
|
121
|
+
this = self
|
122
|
+
ret = bm.scope() do |*args|
|
123
|
+
this.ok {self} != this
|
124
|
+
this.ok {self}.is_a?(Benchmarker::Scope)
|
125
|
+
this.ok {self}.respond_to?(:task)
|
126
|
+
this.ok {self}.respond_to?(:empty_task)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
- spec("[!6h24d] passes benchmark object as argument of block.") do |bm|
|
130
|
+
this = self
|
131
|
+
bm.scope() do |*args|
|
132
|
+
this.ok {args} == [bm]
|
133
|
+
end
|
134
|
+
end
|
135
|
+
- spec("[!y0uwr] returns self.") do |bm|
|
136
|
+
ret = bm.scope() do nil end
|
137
|
+
ok {ret}.same?(bm)
|
138
|
+
end
|
117
139
|
end
|
118
|
-
|
119
|
-
|
140
|
+
|
141
|
+
+ topic('#define_empty_task()') do
|
142
|
+
- spec("[!w66xp] creates empty task.") do |bm|
|
143
|
+
ok {bm.instance_eval{@empty_task}} == nil
|
144
|
+
ret = bm.define_empty_task() do nil end
|
145
|
+
ok {bm.instance_eval{@empty_task}} != nil
|
146
|
+
ok {bm.instance_eval{@empty_task}}.is_a?(Benchmarker::Task)
|
147
|
+
ok {bm.instance_eval{@empty_task}.name} == nil
|
148
|
+
ok {ret}.is_a?(Benchmarker::Task)
|
149
|
+
ok {ret.name} == nil
|
150
|
+
end
|
151
|
+
- spec("[!qzr1s] error when called more than once.") do |bm|
|
152
|
+
pr = proc { bm.define_empty_task() do nil end }
|
153
|
+
ok {pr}.NOT.raise?()
|
154
|
+
ok {pr}.raise?(RuntimeError, "cannot define empty task more than once.")
|
155
|
+
end
|
120
156
|
end
|
121
|
-
end
|
122
157
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
158
|
+
+ topic('#define_task()') do
|
159
|
+
- spec("[!re6b8] creates new task.") do |bm|
|
160
|
+
ret = bm.define_task("foobar") do nil end
|
161
|
+
ok {ret}.is_a?(Benchmarker::Task)
|
162
|
+
ok {ret.name} == "foobar"
|
163
|
+
end
|
164
|
+
- spec("[!r8o0p] can take a tag.") do |bm|
|
165
|
+
ret = bm.define_task("balbla", tag: 'curr') do nil end
|
166
|
+
ok {ret.tag} == "curr"
|
167
|
+
end
|
129
168
|
end
|
130
|
-
|
131
|
-
|
169
|
+
|
170
|
+
+ topic('#define_hook()') do |bm|
|
171
|
+
- spec("[!2u53t] register proc object with symbol key.") do |bm|
|
172
|
+
called = false
|
173
|
+
bm.define_hook(:hook1) do called = true end
|
174
|
+
ok {called} == false
|
175
|
+
bm.__send__(:call_hook, :hook1)
|
176
|
+
ok {called} == true
|
177
|
+
end
|
132
178
|
end
|
133
|
-
|
134
|
-
|
135
|
-
|
179
|
+
|
180
|
+
+ topic('#call_hook()') do |bm|
|
181
|
+
- spec("[!0to2s] calls hook with arguments.") do |bm|
|
182
|
+
args = nil
|
183
|
+
bm.define_hook(:hook2) do |*a| args = a end
|
184
|
+
ok {args} == nil
|
185
|
+
bm.__send__(:call_hook, :hook2, "abc", tag: "xyz")
|
186
|
+
ok {args} == ["abc", {tag: "xyz"}]
|
187
|
+
end
|
136
188
|
end
|
137
|
-
|
138
|
-
|
189
|
+
|
190
|
+
+ topic('#run()') do
|
191
|
+
- spec("[!0fo0l] runs benchmark tasks and reports result.") do |bm|
|
192
|
+
foo_called = false; bar_called = false
|
193
|
+
bm.define_task("foo") do foo_called = true end
|
194
|
+
bm.define_task("bar") do bar_called = true end
|
195
|
+
ok {foo_called} == false
|
196
|
+
ok {bar_called} == false
|
197
|
+
sout, serr = capture_sio do
|
198
|
+
bm.run()
|
199
|
+
end
|
200
|
+
ok {foo_called} == true
|
201
|
+
ok {bar_called} == true
|
202
|
+
ok {serr} == ""
|
203
|
+
ok {sout} =~ /^\#\# benchmarker:/
|
204
|
+
ok {sout} =~ /^foo +/
|
205
|
+
ok {sout} =~ /^bar +/
|
206
|
+
end
|
207
|
+
- spec("[!6h26u] runs preriminary round when `warmup: true` provided.") do |bm|
|
208
|
+
called = 0
|
209
|
+
bm.define_task("foo") do called += 1 end
|
210
|
+
sout, serr = capture_sio do
|
211
|
+
bm.run(warmup: true)
|
212
|
+
end
|
213
|
+
ok {called} == 2
|
214
|
+
n = 0
|
215
|
+
sout.scan(/^## +.*\nfoo +/) { n += 1 }
|
216
|
+
ok {n} == 1
|
217
|
+
end
|
218
|
+
- spec("[!2j4ks] calls 'before_all' hook.") do |bm|
|
219
|
+
called = 0
|
220
|
+
bm.define_hook(:before_all) do called += 1 end
|
221
|
+
ok {called} == 0
|
222
|
+
capture_sio { bm.run() }
|
223
|
+
ok {called} == 1
|
224
|
+
end
|
225
|
+
- spec("[!w1rq7] calls 'after_all' hook even if error raised.") do |bm|
|
226
|
+
called = 0
|
227
|
+
bm.define_hook(:after_all) do called += 1 end
|
228
|
+
bm.define_task("foo") do 1/0 end # raises ZeroDivisionError
|
229
|
+
ok {called} == 0
|
230
|
+
capture_sio do
|
231
|
+
pr = proc { bm.run() }
|
232
|
+
ok {pr}.raise?(ZeroDivisionError)
|
233
|
+
end
|
234
|
+
ok {called} == 1
|
235
|
+
end
|
139
236
|
end
|
140
|
-
end
|
141
237
|
|
142
|
-
|
143
|
-
spec
|
144
|
-
|
145
|
-
|
146
|
-
|
238
|
+
+ topic('#_ignore_output()') do
|
239
|
+
- spec("[!wazs7] ignores output in block argument.") do |bm|
|
240
|
+
called = false
|
241
|
+
sout, serr = capture_sio do
|
242
|
+
puts "aaa"
|
243
|
+
bm.__send__(:_ignore_output) do
|
244
|
+
puts "bbb"
|
245
|
+
called = true
|
246
|
+
end
|
247
|
+
puts "ccc"
|
248
|
+
end
|
249
|
+
ok {called} == true
|
250
|
+
ok {sout} == "aaa\nccc\n"
|
251
|
+
ok {serr} == ""
|
147
252
|
end
|
148
|
-
ok {sout} == Benchmarker.platform()
|
149
253
|
end
|
150
|
-
end
|
151
254
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
255
|
+
+ topic('#filter_tasks()') do
|
256
|
+
def new_bm(filter)
|
257
|
+
bm = Benchmarker::Benchmark.new(filter: filter).scope do
|
258
|
+
task "foo" do nil end
|
259
|
+
task "bar", tag: 'xx' do nil end
|
260
|
+
task "baz", tag: ['xx', 'yy'] do nil end
|
261
|
+
end
|
262
|
+
bm
|
263
|
+
end
|
264
|
+
def task_names(bm)
|
265
|
+
bm.instance_eval {@entries}.collect {|t,_| t.name}
|
266
|
+
end
|
267
|
+
- spec("[!f1n1v] filters tasks by task name when filer string is 'task=...'.") do
|
268
|
+
bm = new_bm('task=bar')
|
269
|
+
ok {task_names(bm)} == ["foo", "bar", "baz"]
|
270
|
+
bm.__send__(:filter_tasks)
|
271
|
+
ok {task_names(bm)} == ["bar"]
|
272
|
+
#
|
273
|
+
bm = new_bm('task=ba*')
|
274
|
+
ok {task_names(bm)} == ["foo", "bar", "baz"]
|
275
|
+
bm.__send__(:filter_tasks)
|
276
|
+
ok {task_names(bm)} == ["bar", "baz"]
|
277
|
+
#
|
278
|
+
bm = new_bm('task=*z')
|
279
|
+
ok {task_names(bm)} == ["foo", "bar", "baz"]
|
280
|
+
bm.__send__(:filter_tasks)
|
281
|
+
ok {task_names(bm)} == ["baz"]
|
282
|
+
#
|
283
|
+
bm = new_bm('task=*xx*')
|
284
|
+
ok {task_names(bm)} == ["foo", "bar", "baz"]
|
285
|
+
bm.__send__(:filter_tasks)
|
286
|
+
ok {task_names(bm)} == []
|
287
|
+
end
|
288
|
+
- spec("[!m79cf] filters tasks by tag value when filer string is 'tag=...'.") do
|
289
|
+
bm = new_bm('tag=xx')
|
290
|
+
bm.__send__(:filter_tasks)
|
291
|
+
ok {task_names(bm)} == ["bar", "baz"]
|
292
|
+
#
|
293
|
+
bm = new_bm('tag=yy')
|
294
|
+
bm.__send__(:filter_tasks)
|
295
|
+
ok {task_names(bm)} == ["baz"]
|
296
|
+
#
|
297
|
+
bm = new_bm('tag=*x')
|
298
|
+
bm.__send__(:filter_tasks)
|
299
|
+
ok {task_names(bm)} == ["bar", "baz"]
|
300
|
+
#
|
301
|
+
bm = new_bm('tag=zz')
|
302
|
+
bm.__send__(:filter_tasks)
|
303
|
+
ok {task_names(bm)} == []
|
304
|
+
end
|
305
|
+
- spec("[!0in0q] supports negative filter by '!=' operator.") do
|
306
|
+
bm = new_bm('task!=bar')
|
307
|
+
bm.__send__(:filter_tasks)
|
308
|
+
ok {task_names(bm)} == ["foo", "baz"]
|
309
|
+
#
|
310
|
+
bm = new_bm('task!=ba*')
|
311
|
+
bm.__send__(:filter_tasks)
|
312
|
+
ok {task_names(bm)} == ["foo"]
|
313
|
+
#
|
314
|
+
bm = new_bm('tag!=xx')
|
315
|
+
bm.__send__(:filter_tasks)
|
316
|
+
ok {task_names(bm)} == ["foo"]
|
317
|
+
#
|
318
|
+
bm = new_bm('tag!=yy')
|
319
|
+
bm.__send__(:filter_tasks)
|
320
|
+
ok {task_names(bm)} == ["foo", "bar"]
|
321
|
+
end
|
322
|
+
- spec("[!g207d] do nothing when filter string is not provided.") do
|
323
|
+
bm = new_bm(nil)
|
324
|
+
bm.__send__(:filter_tasks)
|
325
|
+
ok {task_names(bm)} == ["foo", "bar", "baz"]
|
161
326
|
end
|
162
|
-
ok {tr[0].name} == :all
|
163
|
-
ok {sout} =~ /^## Ranking/
|
164
|
-
ok {sout} =~ /^## Matrix/
|
165
327
|
end
|
166
|
-
end
|
167
328
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
329
|
+
+ topic('#invoke_tasks()') do
|
330
|
+
def new_bm(**kwargs)
|
331
|
+
called = []
|
332
|
+
bm = Benchmarker::Benchmark.new(**kwargs).scope do
|
333
|
+
empty_task do called << :empty end
|
334
|
+
task "foo" do called << :foo end
|
335
|
+
task "bar" do called << :bar end
|
336
|
+
task "baz" do called << :baz end
|
337
|
+
end
|
338
|
+
return bm, called
|
339
|
+
end
|
340
|
+
class Task2 < Benchmarker::Task
|
341
|
+
def invoke(loop=1)
|
342
|
+
super
|
343
|
+
case @name
|
344
|
+
when nil ; a = [0.002, 0.001, 0.003, 0.0031]
|
345
|
+
when "foo" ; a = [0.005, 0.003, 0.008, 0.0085]
|
346
|
+
when "bar" ; a = [0.007, 0.004, 0.011, 0.0115]
|
347
|
+
when "baz" ; a = [0.009, 0.005, 0.014, 0.0145]
|
348
|
+
else ; raise "** internal error"
|
180
349
|
end
|
350
|
+
Benchmarker::TimeSet.new(*a)
|
181
351
|
end
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
352
|
+
end
|
353
|
+
def with_dummy_task_class()
|
354
|
+
Benchmarker.module_eval { remove_const :TASK; const_set :TASK, Task2 }
|
355
|
+
yield
|
356
|
+
ensure
|
357
|
+
Benchmarker.module_eval { remove_const :TASK; const_set :TASK, Benchmarker::Task }
|
358
|
+
end
|
359
|
+
- spec("[!3hgos] invokes empty task at first if defined.") do
|
360
|
+
bm, called = new_bm()
|
361
|
+
sout, serr = capture_sio { bm.__send__(:invoke_tasks) }
|
362
|
+
ok {called.first} == :empty
|
363
|
+
ok {sout} =~ /^## +.*\n\(Empty\) +/
|
364
|
+
end
|
365
|
+
- spec("[!xf84h] invokes all tasks.") do
|
366
|
+
bm, called = new_bm()
|
367
|
+
sout, serr = capture_sio { bm.__send__(:invoke_tasks) }
|
368
|
+
ok {called} == [:empty, :foo, :bar, :baz]
|
369
|
+
ok {sout} =~ /^\(Empty\) +.*\nfoo +.*\nbar +.*\nbaz +.*\n/
|
370
|
+
end
|
371
|
+
- spec("[!6g36c] invokes task with validator if validator defined.") do
|
372
|
+
bm = Benchmarker::Benchmark.new().scope do
|
373
|
+
task "foo" do 100 end
|
374
|
+
task "bar" do 123 end
|
375
|
+
validate do |actual, name|
|
376
|
+
actual == 100 or
|
377
|
+
raise "task(#{name.inspect}): #{actual.inspect} == 100: failed."
|
194
378
|
end
|
195
379
|
end
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
ok {
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
ok {
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
380
|
+
pr = proc do
|
381
|
+
capture_sio { bm.__send__(:invoke_tasks) }
|
382
|
+
end
|
383
|
+
ok {pr}.raise?(RuntimeError, "task(\"bar\"): 123 == 100: failed.")
|
384
|
+
end
|
385
|
+
- spec("[!c8yak] invokes tasks once if 'iter' option not specified.") do
|
386
|
+
bm, called = new_bm(iter: nil)
|
387
|
+
sout, serr = capture_sio { bm.__send__(:invoke_tasks) }
|
388
|
+
ok {called} == [:empty, :foo, :bar, :baz] * 1
|
389
|
+
ok {sout} !~ /^## \(#\d\)/
|
390
|
+
end
|
391
|
+
- spec("[!unond] invokes tasks multiple times if 'iter' option specified.") do
|
392
|
+
bm, called = new_bm(iter: 5)
|
393
|
+
sout, serr = capture_sio { bm.__send__(:invoke_tasks) }
|
394
|
+
ok {called} == [:empty, :foo, :bar, :baz] * 5
|
395
|
+
ok {sout} =~ /^## \(#1\)/
|
396
|
+
ok {sout} =~ /^## \(#5\)/
|
397
|
+
end
|
398
|
+
- spec("[!wzvdb] invokes tasks 16 times if 'iter' is 10 and 'extra' is 3.") do
|
399
|
+
bm, called = new_bm(iter: 10, extra: 3)
|
400
|
+
sout, serr = capture_sio { bm.__send__(:invoke_tasks) }
|
401
|
+
ok {called} == [:empty, :foo, :bar, :baz] * 16
|
402
|
+
ok {sout} =~ /^## \(#1\)/
|
403
|
+
ok {sout} =~ /^## \(#16\)/
|
404
|
+
end
|
405
|
+
- spec("[!hbass] calls 'before' hook with task name and tag.") do
|
406
|
+
called = 0
|
407
|
+
argslist = []
|
408
|
+
bm = Benchmarker::Benchmark.new().scope do
|
409
|
+
before do |*a| called += 1; argslist << a end
|
410
|
+
task "foo" do nil end
|
411
|
+
task "bar", tag: 'yy' do nil end
|
412
|
+
end
|
413
|
+
ok {called} == 0
|
414
|
+
ok {argslist} == []
|
415
|
+
capture_sio { bm.__send__(:invoke_tasks) }
|
416
|
+
ok {called} == 2
|
417
|
+
ok {argslist} == [["foo", nil], ["bar", 'yy']]
|
418
|
+
end
|
419
|
+
- spec("[!7960c] calls 'after' hook with task name and tag even if error raised.") do
|
420
|
+
called = 0
|
421
|
+
argslist = []
|
422
|
+
bm = Benchmarker::Benchmark.new().scope do
|
423
|
+
after do |*a| called += 1; argslist << a end
|
424
|
+
task "foo" do nil end
|
425
|
+
task "bar", tag: 'yy' do 1/0 end # raises ZeroDivisionError
|
426
|
+
task "baz", tag: 'zz' do nil end
|
427
|
+
end
|
428
|
+
ok {called} == 0
|
429
|
+
ok {argslist} == []
|
430
|
+
capture_sio do
|
431
|
+
pr = proc { bm.__send__(:invoke_tasks) }
|
432
|
+
ok {pr}.raise?(ZeroDivisionError)
|
433
|
+
end
|
434
|
+
ok {called} == 2
|
435
|
+
ok {argslist} == [["foo", nil], ["bar", 'yy']]
|
436
|
+
end
|
437
|
+
- spec("[!fv4cv] skips task invocation if skip reason is specified.") do
|
438
|
+
called = []
|
439
|
+
bm = Benchmarker::Benchmark.new().scope do
|
440
|
+
empty_task do called << :empty end
|
441
|
+
task "foo" do called << :foo end
|
442
|
+
task "bar", skip: "not installed" do called << :bar end
|
443
|
+
task "baz" do called << :baz end
|
444
|
+
end
|
445
|
+
sout, serr = capture_sio { bm.__send__(:invoke_tasks) }
|
446
|
+
ok {called} == [:empty, :foo, :baz] # :bar is not included
|
447
|
+
end
|
448
|
+
- spec("[!dyofw] prints reason if 'skip:' option specified.") do
|
449
|
+
bm = Benchmarker::Benchmark.new().scope do
|
450
|
+
task "foo" do nil end
|
451
|
+
task "bar", skip: "not installed" do nil end
|
452
|
+
task "baz" do nil end
|
453
|
+
end
|
454
|
+
sout, serr = capture_sio { bm.__send__(:invoke_tasks) }
|
455
|
+
ok {sout} =~ /^bar +\# Skipped \(reason: not installed\)$/
|
456
|
+
end
|
457
|
+
- spec("[!ygpx0] records reason of skip into JSON data.") do
|
458
|
+
with_dummy_task_class do
|
459
|
+
bm = Benchmarker::Benchmark.new().scope do
|
460
|
+
task "foo" do nil end
|
461
|
+
task "bar", skip: "not installed" do nil end
|
462
|
+
task "baz" do nil end
|
228
463
|
end
|
464
|
+
sout, serr = capture_sio { bm.__send__(:invoke_tasks) }
|
465
|
+
ok {bm.instance_eval{@jdata}} == {
|
466
|
+
:Results => [
|
467
|
+
[
|
468
|
+
["foo", 0.005, 0.003, 0.008, 0.0085],
|
469
|
+
["bar", nil, nil, nil, nil, "not installed"],
|
470
|
+
["baz", 0.009, 0.005, 0.014, 0.0145],
|
471
|
+
]
|
472
|
+
]
|
473
|
+
}
|
229
474
|
end
|
230
|
-
ok {i} == 1
|
231
|
-
ok {sout} =~ /^## *user/
|
232
475
|
end
|
233
|
-
|
234
|
-
|
476
|
+
- spec("[!513ok] subtract timeset of empty loop from timeset of each task.") do
|
477
|
+
with_dummy_task_class do
|
478
|
+
bm, called = new_bm()
|
479
|
+
sout, serr = capture_sio { bm.__send__(:invoke_tasks) }
|
480
|
+
sout =~ /^foo +0\.0030 0\.0020 0\.0050 0\.0054$/
|
481
|
+
sout =~ /^bar +0\.0050 0\.0030 0\.0080 0\.0084$/
|
482
|
+
sout =~ /^baz +0\.0070 0\.0040 0\.0110 0\.0114$/
|
483
|
+
end
|
484
|
+
end
|
485
|
+
- spec("[!yg9i7] prints result unless quiet mode.") do
|
486
|
+
with_dummy_task_class do
|
487
|
+
bm, _ = new_bm()
|
488
|
+
sout, serr = capture_sio { bm.__send__(:invoke_tasks) }
|
489
|
+
ok {sout} =~ /^## .* +user sys total real$/
|
490
|
+
ok {sout} =~ /^\(Empty\) +\d+\.\d+ +\d+\.\d+ +\d+\.\d+ +\d+\.\d+$/
|
491
|
+
ok {sout} =~ /^foo +\d+\.\d+ +\d+\.\d+ +\d+\.\d+ +\d+\.\d+$/
|
492
|
+
ok {sout} =~ /^bar +\d+\.\d+ +\d+\.\d+ +\d+\.\d+ +\d+\.\d+$/
|
493
|
+
ok {sout} =~ /^baz +\d+\.\d+ +\d+\.\d+ +\d+\.\d+ +\d+\.\d+$/
|
494
|
+
end
|
495
|
+
end
|
496
|
+
- spec("[!94916] suppresses result if quiet mode.") do
|
497
|
+
with_dummy_task_class do
|
498
|
+
bm, _ = new_bm(quiet: true, iter: 2)
|
499
|
+
sout, serr = capture_sio { bm.__send__(:invoke_tasks) }
|
500
|
+
ok {sout} !~ /^## .* +user sys total real$/
|
501
|
+
ok {sout} !~ /^\(Empty\) +\d+\.\d+ +\d+\.\d+ +\d+\.\d+ +\d+\.\d+$/
|
502
|
+
ok {sout} !~ /^foo +\d+\.\d+ +\d+\.\d+ +\d+\.\d+ +\d+\.\d+$/
|
503
|
+
ok {sout} !~ /^bar +\d+\.\d+ +\d+\.\d+ +\d+\.\d+ +\d+\.\d+$/
|
504
|
+
ok {sout} !~ /^baz +\d+\.\d+ +\d+\.\d+ +\d+\.\d+ +\d+\.\d+$/
|
505
|
+
end
|
506
|
+
end
|
507
|
+
- spec("[!5axhl] prints result even on quiet mode if no 'iter' nor 'extra'.") do
|
508
|
+
with_dummy_task_class do
|
509
|
+
bm, _ = new_bm(quiet: true)
|
510
|
+
sout, serr = capture_sio { bm.__send__(:invoke_tasks) }
|
511
|
+
ok {sout} =~ /^## .* +user sys total real$/
|
512
|
+
ok {sout} =~ /^\(Empty\) +\d+\.\d+ +\d+\.\d+ +\d+\.\d+ +\d+\.\d+$/
|
513
|
+
ok {sout} =~ /^foo +\d+\.\d+ +\d+\.\d+ +\d+\.\d+ +\d+\.\d+$/
|
514
|
+
ok {sout} =~ /^bar +\d+\.\d+ +\d+\.\d+ +\d+\.\d+ +\d+\.\d+$/
|
515
|
+
ok {sout} =~ /^baz +\d+\.\d+ +\d+\.\d+ +\d+\.\d+ +\d+\.\d+$/
|
516
|
+
end
|
517
|
+
end
|
518
|
+
- spec("[!knjls] records result of empty loop into JSON data.") do
|
519
|
+
with_dummy_task_class do
|
520
|
+
bm, _ = new_bm()
|
521
|
+
capture_sio { bm.__send__(:invoke_tasks) }
|
522
|
+
jdata = bm.instance_variable_get(:@jdata)
|
523
|
+
ok {jdata}.key?(:Results)
|
524
|
+
ok {jdata[:Results][0][0]} == ["(Empty)", 0.002, 0.001, 0.003, 0.0031]
|
525
|
+
end
|
526
|
+
end
|
527
|
+
- spec("[!ejxif] records result of each task into JSON data.") do
|
528
|
+
with_dummy_task_class do
|
529
|
+
bm, _ = new_bm()
|
530
|
+
capture_sio { bm.__send__(:invoke_tasks) }
|
531
|
+
jdata = bm.instance_variable_get(:@jdata)
|
532
|
+
ok {jdata}.key?(:Results)
|
533
|
+
ok {jdata[:Results]} == [
|
534
|
+
[
|
535
|
+
["(Empty)", 0.002, 0.001, 0.003, 0.0031],
|
536
|
+
["foo" , 0.003, 0.002, 0.005, 0.0054],
|
537
|
+
["bar" , 0.005, 0.003, 0.008, 0.0084],
|
538
|
+
["baz" , 0.007, 0.004, 0.011, 0.0114],
|
539
|
+
],
|
540
|
+
]
|
541
|
+
#
|
542
|
+
bm, _ = new_bm(iter: 3)
|
543
|
+
capture_sio { bm.__send__(:invoke_tasks) }
|
544
|
+
jdata = bm.instance_variable_get(:@jdata)
|
545
|
+
ok {jdata}.key?(:Results)
|
546
|
+
result = [
|
547
|
+
["(Empty)", 0.002, 0.001, 0.003, 0.0031],
|
548
|
+
["foo" , 0.003, 0.002, 0.005, 0.0054],
|
549
|
+
["bar" , 0.005, 0.003, 0.008, 0.0084],
|
550
|
+
["baz" , 0.007, 0.004, 0.011, 0.0114],
|
551
|
+
]
|
552
|
+
ok {jdata[:Results]} == [result, result, result]
|
553
|
+
end
|
554
|
+
end
|
555
|
+
- spec("[!vbhvz] sleeps N seconds after each task if `sleep` option specified.") do
|
556
|
+
new_bm = proc {|kwargs|
|
557
|
+
Benchmarker::Benchmark.new(**kwargs).scope do
|
558
|
+
empty_task do nil end
|
559
|
+
task "foo" do nil end
|
560
|
+
task "bar" do nil end
|
561
|
+
end
|
562
|
+
}
|
563
|
+
#
|
564
|
+
bm = new_bm.call({})
|
565
|
+
start = Time.now
|
566
|
+
capture_sio { bm.__send__(:invoke_tasks) }
|
567
|
+
ok {Time.now - start} < 0.1
|
568
|
+
#
|
569
|
+
bm = new_bm.call({sleep: 1})
|
570
|
+
start = Time.now
|
571
|
+
capture_sio { bm.__send__(:invoke_tasks) }
|
572
|
+
ok {Time.now - start} > 3.0
|
235
573
|
end
|
236
574
|
end
|
237
|
-
end
|
238
575
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
sos.call("Haruhi", 11.1, 0.2, 11.3, 11.9),
|
255
|
-
sos.call("Mikuru", 14.1, 0.2, 14.3, 14.2),
|
256
|
-
sos.call("Yuki", 10.1, 0.2, 10.3, 10.6),
|
257
|
-
sos.call("Itsuki", 12.1, 0.2, 12.3, 12.5),
|
258
|
-
sos.call("Kyon", 13.1, 0.2, 13.3, 13.3),
|
259
|
-
]
|
260
|
-
all_tasks << [
|
261
|
-
sos.call("Haruhi", 11.1, 0.2, 11.3, 11.5),
|
262
|
-
sos.call("Mikuru", 14.1, 0.2, 14.3, 14.8),
|
263
|
-
sos.call("Yuki", 10.1, 0.2, 10.3, 10.9),
|
264
|
-
sos.call("Itsuki", 12.1, 0.2, 12.3, 12.7),
|
265
|
-
sos.call("Kyon", 13.1, 0.2, 13.3, 13.9),
|
266
|
-
]
|
267
|
-
all_tasks << [
|
268
|
-
sos.call("Haruhi", 11.1, 0.2, 11.3, 11.3),
|
269
|
-
sos.call("Mikuru", 14.1, 0.2, 14.3, 14.2),
|
270
|
-
sos.call("Yuki", 10.1, 0.2, 10.3, 10.3),
|
271
|
-
sos.call("Itsuki", 12.1, 0.2, 12.3, 12.8),
|
272
|
-
sos.call("Kyon", 13.1, 0.2, 13.3, 13.4),
|
273
|
-
]
|
274
|
-
all_tasks << [
|
275
|
-
sos.call("Haruhi", 11.1, 0.2, 11.3, 11.6),
|
276
|
-
sos.call("Mikuru", 14.1, 0.2, 14.3, 14.2),
|
277
|
-
sos.call("Yuki", 10.1, 0.2, 10.3, 10.6),
|
278
|
-
sos.call("Itsuki", 12.1, 0.2, 12.3, 12.4),
|
279
|
-
sos.call("Kyon", 13.1, 0.2, 13.3, 13.3),
|
280
|
-
]
|
281
|
-
all_tasks << [
|
282
|
-
sos.call("Haruhi", 11.1, 0.2, 11.3, 11.3),
|
283
|
-
sos.call("Mikuru", 14.1, 0.2, 14.3, 14.8),
|
284
|
-
sos.call("Yuki", 10.1, 0.2, 10.3, 10.3),
|
285
|
-
sos.call("Itsuki", 12.1, 0.2, 12.3, 12.2),
|
286
|
-
sos.call("Kyon", 13.1, 0.2, 13.3, 13.7),
|
287
|
-
]
|
288
|
-
#
|
289
|
-
expected = <<'END'
|
290
|
-
|
291
|
-
## Remove Min & Max min cycle max cycle
|
292
|
-
Haruhi 11.3000 (#1) 11.9000 (#2)
|
293
|
-
11.3000 (#6) 11.6000 (#5)
|
294
|
-
Mikuru 14.1000 (#1) 14.8000 (#6)
|
295
|
-
14.2000 (#2) 14.8000 (#3)
|
296
|
-
Yuki 10.3000 (#6) 10.9000 (#3)
|
297
|
-
10.3000 (#4) 10.6000 (#5)
|
298
|
-
Itsuki 12.1000 (#1) 12.8000 (#4)
|
299
|
-
12.2000 (#6) 12.7000 (#3)
|
300
|
-
Kyon 13.3000 (#5) 13.9000 (#3)
|
301
|
-
13.3000 (#2) 13.7000 (#6)
|
302
|
-
|
303
|
-
## Average of 2 user sys total real
|
304
|
-
Haruhi 11.1000 0.2000 11.3000 11.4000
|
305
|
-
Mikuru 14.1000 0.2000 14.3000 14.2000
|
306
|
-
Yuki 10.1000 0.2000 10.3000 10.5000
|
307
|
-
Itsuki 12.1000 0.2000 12.3000 12.4500
|
308
|
-
Kyon 13.1000 0.2000 13.3000 13.4500
|
309
|
-
END
|
310
|
-
#
|
311
|
-
spec "calculates average times of tasks." do
|
312
|
-
avg_tasks = nil
|
313
|
-
sout, serr = dummy_io() do
|
314
|
-
runner = Benchmarker::RUNNER.new(:cycle=>2)
|
315
|
-
avg_tasks = runner.__send__(:_calc_averages, all_tasks, 2)
|
316
|
-
runner.__send__(:_report_average_section, avg_tasks)
|
576
|
+
+ topic('#ignore_skipped_tasks()') do
|
577
|
+
def task_names(bm)
|
578
|
+
bm.instance_eval {@entries}.collect {|t,_| t.name}
|
579
|
+
end
|
580
|
+
- spec("[!5gpo7] removes skipped tasks and leaves other tasks.") do
|
581
|
+
bm = Benchmarker::Benchmark.new().scope do
|
582
|
+
empty_task do nil end
|
583
|
+
task "foo", skip: "not installed" do nil end
|
584
|
+
task "bar", skip: "not installed" do nil end
|
585
|
+
task "baz" do nil end
|
586
|
+
end
|
587
|
+
capture_sio { bm.__send__(:invoke_tasks) }
|
588
|
+
ok {task_names(bm)} == ["foo", "bar", "baz"]
|
589
|
+
bm.__send__(:ignore_skipped_tasks)
|
590
|
+
ok {task_names(bm)} == ["baz"]
|
317
591
|
end
|
318
|
-
ok {sout} == expected
|
319
592
|
end
|
320
|
-
end
|
321
593
|
|
322
|
-
|
323
|
-
spec
|
324
|
-
|
325
|
-
|
326
|
-
|
594
|
+
+ topic('#report_environment()') do
|
595
|
+
- spec("[!rx7nn] prints ruby version, platform, several options, and so on.") do
|
596
|
+
bm = Benchmarker::Benchmark.new(title: "string concat", loop: 1000, inverse: true)
|
597
|
+
sout, serr = capture_sio { bm.__send__(:report_environment) }
|
598
|
+
ok {serr} == ""
|
599
|
+
ok {sout} =~ /^## title: +string concat$/
|
600
|
+
ok {sout} =~ /^## options: +loop=1000, iter=1, extra=0, inverse=true$/
|
601
|
+
ok {sout} =~ /^## benchmarker: +release \d+\.\d+\.\d+$/
|
602
|
+
ok {sout} =~ /^## ruby engine: +\w+ \(engine version .*\)$/
|
603
|
+
ok {sout} =~ /^## ruby platform: +.+$/
|
604
|
+
ok {sout} =~ /^## ruby path: +.+$/
|
605
|
+
ok {sout} =~ /^## compiler: +.*$/
|
606
|
+
ok {sout} =~ /^## cpu model: +.+$/
|
607
|
+
end
|
327
608
|
end
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
609
|
+
|
610
|
+
fixture :bm5 do
|
611
|
+
bm = Benchmarker::Benchmark.new(iter: 5, extra: 2).scope do
|
612
|
+
task "foo" do nil end
|
613
|
+
task "bar" do nil end
|
614
|
+
end
|
615
|
+
entries = bm.instance_eval{@entries}
|
616
|
+
#ok {entries[0][1]}.is_a?(Benchmarker::Result)
|
617
|
+
#ok {entries[1][1]}.is_a?(Benchmarker::Result)
|
618
|
+
#
|
619
|
+
entries[0][1].add(Benchmarker::TimeSet.new(1.1, 2.1, 3.1, 4.3))
|
620
|
+
entries[0][1].add(Benchmarker::TimeSet.new(1.2, 2.2, 3.2, 4.1))
|
621
|
+
entries[0][1].add(Benchmarker::TimeSet.new(1.3, 2.3, 3.3, 4.4))
|
622
|
+
entries[0][1].add(Benchmarker::TimeSet.new(1.4, 2.4, 3.4, 4.5))
|
623
|
+
entries[0][1].add(Benchmarker::TimeSet.new(1.5, 2.5, 3.5, 4.9))
|
624
|
+
entries[0][1].add(Benchmarker::TimeSet.new(1.6, 2.6, 3.6, 4.2))
|
625
|
+
entries[0][1].add(Benchmarker::TimeSet.new(1.7, 2.7, 3.7, 4.6))
|
626
|
+
entries[0][1].add(Benchmarker::TimeSet.new(1.8, 2.8, 3.8, 4.8))
|
627
|
+
entries[0][1].add(Benchmarker::TimeSet.new(1.9, 2.9, 3.9, 4.7))
|
628
|
+
#
|
629
|
+
entries[1][1].add(Benchmarker::TimeSet.new(1.1, 2.1, 3.1, 4.3))
|
630
|
+
entries[1][1].add(Benchmarker::TimeSet.new(1.2, 2.2, 3.2, 4.1))
|
631
|
+
entries[1][1].add(Benchmarker::TimeSet.new(1.3, 2.3, 3.3, 4.4))
|
632
|
+
entries[1][1].add(Benchmarker::TimeSet.new(1.4, 2.4, 3.4, 4.5))
|
633
|
+
entries[1][1].add(Benchmarker::TimeSet.new(1.5, 2.5, 3.5, 4.9))
|
634
|
+
entries[1][1].add(Benchmarker::TimeSet.new(1.6, 2.6, 3.6, 4.2))
|
635
|
+
entries[1][1].add(Benchmarker::TimeSet.new(1.7, 2.7, 3.7, 4.6))
|
636
|
+
entries[1][1].add(Benchmarker::TimeSet.new(1.8, 2.8, 3.8, 4.8))
|
637
|
+
entries[1][1].add(Benchmarker::TimeSet.new(1.9, 2.9, 3.9, 4.7))
|
638
|
+
#
|
639
|
+
bm
|
332
640
|
end
|
333
|
-
end
|
334
641
|
|
335
|
-
|
642
|
+
+ topic('#_removed_minmax()') do
|
643
|
+
- spec("[!uxe7e] removes best and worst results if 'extra' option specified.") do |bm5|
|
644
|
+
bm5.__send__(:_remove_minmax)
|
645
|
+
arr = bm5.instance_eval{@entries}.collect {|task, r|
|
646
|
+
real_list = []
|
647
|
+
r.each {|t| real_list << t.real }
|
648
|
+
[task.name, real_list]
|
649
|
+
}
|
650
|
+
ok {arr} == [
|
651
|
+
["foo", [4.30, 4.40, 4.50, 4.60, 4.70]],
|
652
|
+
["bar", [4.30, 4.40, 4.50, 4.60, 4.70]],
|
653
|
+
]
|
654
|
+
end
|
655
|
+
- spec("[!is6ll] returns removed min and max data.") do |bm5|
|
656
|
+
rows = bm5.__send__(:_remove_minmax)
|
657
|
+
ok {rows} == [
|
658
|
+
["foo", 4.10, "(#2)", 4.90, "(#5)"],
|
659
|
+
[nil , 4.20, "(#6)", 4.80, "(#8)"],
|
660
|
+
["bar", 4.10, "(#2)", 4.90, "(#5)"],
|
661
|
+
[nil , 4.20, "(#6)", 4.80, "(#8)"],
|
662
|
+
]
|
663
|
+
end
|
664
|
+
- spec("[!xwddz] sets removed best and worst results into JSON data.") do |bm5|
|
665
|
+
bm5.__send__(:_remove_minmax)
|
666
|
+
ok {bm5.instance_eval{@jdata}} == {
|
667
|
+
:RemovedMinMax => [
|
668
|
+
["foo", 4.10, "(#2)", 4.90, "(#5)"],
|
669
|
+
[nil , 4.20, "(#6)", 4.80, "(#8)"],
|
670
|
+
["bar", 4.10, "(#2)", 4.90, "(#5)"],
|
671
|
+
[nil , 4.20, "(#6)", 4.80, "(#8)"],
|
672
|
+
]
|
673
|
+
}
|
674
|
+
end
|
675
|
+
end
|
336
676
|
|
677
|
+
+ topic('#_render_minmax()') do
|
678
|
+
- spec("[!p71ax] returns rendered string.") do |bm5|
|
679
|
+
rows = bm5.__send__(:_remove_minmax)
|
680
|
+
str = bm5.__send__(:_render_minmax, rows)
|
681
|
+
ok {str} == <<"END"
|
337
682
|
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
@task1.real = 2.25
|
347
|
-
@task2 = Benchmarker::TASK.new("label1")
|
348
|
-
@task2.user = 1.125
|
349
|
-
@task2.sys = 0.25
|
350
|
-
@task2.total = 1.375
|
351
|
-
@task2.real = 1.5
|
352
|
-
end
|
683
|
+
## Removed Min & Max min iter max iter
|
684
|
+
foo \e[0;36m 4.1000\e[0m \e[0;35m (#2)\e[0m \e[0;36m 4.9000\e[0m \e[0;35m (#5)\e[0m
|
685
|
+
\e[0;36m 4.2000\e[0m \e[0;35m (#6)\e[0m \e[0;36m 4.8000\e[0m \e[0;35m (#8)\e[0m
|
686
|
+
bar \e[0;36m 4.1000\e[0m \e[0;35m (#2)\e[0m \e[0;36m 4.9000\e[0m \e[0;35m (#5)\e[0m
|
687
|
+
\e[0;36m 4.2000\e[0m \e[0;35m (#6)\e[0m \e[0;36m 4.8000\e[0m \e[0;35m (#8)\e[0m
|
688
|
+
END
|
689
|
+
end
|
690
|
+
end
|
353
691
|
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
692
|
+
+ topic('#_calc_average()') do
|
693
|
+
- spec("[!qu29s] calculates average of real times for each task.") do |bm5|
|
694
|
+
rows = bm5.__send__(:_calc_average)
|
695
|
+
ok {rows} == [
|
696
|
+
["foo", 1.50, 2.50, 3.50, 4.50],
|
697
|
+
["bar", 1.50, 2.50, 3.50, 4.50],
|
698
|
+
]
|
699
|
+
end
|
700
|
+
- spec("[!jxf28] sets average results into JSON data.") do |bm5|
|
701
|
+
bm5.__send__(:_calc_average)
|
702
|
+
ok {bm5.instance_eval{@jdata}} == {
|
703
|
+
:Average => [
|
704
|
+
["foo", 1.50, 2.50, 3.50, 4.50],
|
705
|
+
["bar", 1.50, 2.50, 3.50, 4.50],
|
706
|
+
]
|
707
|
+
}
|
708
|
+
end
|
360
709
|
end
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
710
|
+
|
711
|
+
+ topic('#_render_average()') do
|
712
|
+
- spec("[!j9wlv] returns rendered string.") do |bm5|
|
713
|
+
rows = bm5.__send__(:_calc_average)
|
714
|
+
str = bm5.__send__(:_render_average, rows)
|
715
|
+
ok {str} == <<"END"
|
716
|
+
|
717
|
+
## Average of 5 (=9-2*2) user sys total real
|
718
|
+
foo 1.5000 2.5000 3.5000 \e[0;36m 4.5000\e[0m
|
719
|
+
bar 1.5000 2.5000 3.5000 \e[0;36m 4.5000\e[0m
|
720
|
+
END
|
721
|
+
end
|
366
722
|
end
|
367
|
-
end
|
368
723
|
|
369
|
-
|
370
|
-
spec
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
724
|
+
+ topic('#report_stats()') do
|
725
|
+
- spec("[!0jn7d] sorts results by real sec.") do
|
726
|
+
bm = Benchmarker::Benchmark.new().scope do
|
727
|
+
task "foo" do nil end
|
728
|
+
task "bar" do nil end
|
729
|
+
task "baz" do nil end
|
730
|
+
end
|
731
|
+
entries = bm.instance_eval{@entries}
|
732
|
+
entries[0][1].add(Benchmarker::TimeSet.new(1.1, 2.1, 3.2, 4.3))
|
733
|
+
entries[1][1].add(Benchmarker::TimeSet.new(1.1, 2.1, 3.2, 3.3))
|
734
|
+
entries[2][1].add(Benchmarker::TimeSet.new(1.1, 2.1, 3.2, 5.3))
|
735
|
+
#
|
736
|
+
sout, serr = capture_sio { bm.__send__(:report_stats) }
|
737
|
+
ok {sout} == <<'END'
|
738
|
+
|
739
|
+
## Ranking real
|
740
|
+
bar 3.3000 (100.0%) ********************
|
741
|
+
foo 4.3000 ( 76.7%) ***************
|
742
|
+
baz 5.3000 ( 62.3%) ************
|
743
|
+
|
744
|
+
## Matrix real [1] [2] [3]
|
745
|
+
[1] bar 3.3000 100.0% 130.3% 160.6%
|
746
|
+
[2] foo 4.3000 76.7% 100.0% 123.3%
|
747
|
+
[3] baz 5.3000 62.3% 81.1% 100.0%
|
748
|
+
END
|
749
|
+
end
|
389
750
|
end
|
390
|
-
end
|
391
751
|
|
392
|
-
|
393
|
-
|
394
|
-
|
752
|
+
fixture :pairs do
|
753
|
+
[
|
754
|
+
["foo", 1.11],
|
755
|
+
["bar", 2.22],
|
756
|
+
["baz", 3.33],
|
757
|
+
]
|
395
758
|
end
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
759
|
+
|
760
|
+
+ topic('#_render_ranking()') do
|
761
|
+
- spec("[!2lu55] calculates ranking data and sets it into JSON data.") do |bm, pairs|
|
762
|
+
bm.__send__(:_render_ranking, pairs)
|
763
|
+
ok {bm.instance_eval{@jdata}} == {
|
764
|
+
:Ranking => [
|
765
|
+
["foo", 1.11, "100.0%", "0.90 times/sec", "********************"],
|
766
|
+
["bar", 2.22, "50.0%", "0.45 times/sec", "**********" ],
|
767
|
+
["baz", 3.33, "33.3%", "0.30 times/sec", "*******" ],
|
768
|
+
]
|
769
|
+
}
|
770
|
+
end
|
771
|
+
- spec("[!55x8r] returns rendered string of ranking.") do |bm, pairs|
|
772
|
+
str = bm.__send__(:_render_ranking, pairs)
|
773
|
+
ok {str} == <<"END"
|
774
|
+
|
775
|
+
## Ranking real
|
776
|
+
foo \e[0;36m 1.1100\e[0m (100.0%) ********************
|
777
|
+
bar \e[0;36m 2.2200\e[0m ( 50.0%) **********
|
778
|
+
baz \e[0;36m 3.3300\e[0m ( 33.3%) *******
|
779
|
+
END
|
780
|
+
end
|
401
781
|
end
|
402
|
-
end
|
403
782
|
|
404
|
-
|
405
|
-
spec
|
406
|
-
|
783
|
+
+ topic('#_render_matrix()') do
|
784
|
+
- spec("[!2lu55] calculates ranking data and sets it into JSON data.") do |bm, pairs|
|
785
|
+
bm.__send__(:_render_matrix, pairs)
|
786
|
+
ok {bm.instance_eval{@jdata}} == {
|
787
|
+
:Matrix => [
|
788
|
+
["[1] foo", 1.11, "100.0%", "200.0%", "300.0%"],
|
789
|
+
["[2] bar", 2.22, "50.0%", "100.0%", "150.0%"],
|
790
|
+
["[3] baz", 3.33, "33.3%", "66.7%", "100.0%"],
|
791
|
+
]
|
792
|
+
}
|
793
|
+
end
|
794
|
+
- spec("[!rwfxu] returns rendered string of matrix.") do |bm, pairs|
|
795
|
+
str = bm.__send__(:_render_matrix, pairs)
|
796
|
+
ok {str} == <<"END"
|
797
|
+
|
798
|
+
## Matrix real [1] [2] [3]
|
799
|
+
[1] foo \e[0;36m 1.1100\e[0m 100.0% 200.0% 300.0%
|
800
|
+
[2] bar \e[0;36m 2.2200\e[0m 50.0% 100.0% 150.0%
|
801
|
+
[3] baz \e[0;36m 3.3300\e[0m 33.3% 66.7% 100.0%
|
802
|
+
END
|
803
|
+
end
|
407
804
|
end
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
805
|
+
|
806
|
+
+ topic('#write_outfile()') do
|
807
|
+
- spec("[!o8ah6] writes result data into JSON file if 'outfile' option specified.") do
|
808
|
+
tmpfile = "tmp#{rand().to_s[2..6]}.json"
|
809
|
+
at_end { File.unlink tmpfile if File.exist?(tmpfile) }
|
810
|
+
jdata = {
|
811
|
+
:Ranking => [
|
812
|
+
["foo", 1.11, "100.0%", "0.90 times/sec", "********************"],
|
813
|
+
["bar", 2.22, "50.0%", "0.45 times/sec", "**********" ],
|
814
|
+
["baz", 3.33, "33.3%", "0.30 times/sec", "*******" ],
|
815
|
+
],
|
816
|
+
:Matrix => [
|
817
|
+
["[1] foo", 1.11, "100.0%", "200.0%", "300.0%"],
|
818
|
+
["[2] bar", 2.22, "50.0%", "100.0%", "150.0%"],
|
819
|
+
["[3] baz", 3.33, "33.3%", "66.7%", "100.0%"],
|
820
|
+
],
|
821
|
+
}
|
822
|
+
#
|
823
|
+
bm1 = Benchmarker::Benchmark.new()
|
824
|
+
bm1.instance_eval { @jdata = jdata }
|
825
|
+
bm1.__send__(:write_outfile)
|
826
|
+
ok {tmpfile}.NOT.file_exist?
|
827
|
+
#
|
828
|
+
bm2 = Benchmarker::Benchmark.new(outfile: tmpfile)
|
829
|
+
bm2.instance_eval { @jdata = jdata }
|
830
|
+
bm2.__send__(:write_outfile)
|
831
|
+
ok {tmpfile}.file_exist?
|
832
|
+
actual = JSON.load(File.read(tmpfile))
|
833
|
+
ok {actual} == {"Ranking"=>jdata[:Ranking], "Matrix"=>jdata[:Matrix]}
|
834
|
+
end
|
413
835
|
end
|
836
|
+
|
837
|
+
+ topic('#colorize?') do
|
838
|
+
- spec("[!cy10n] returns true if '-c' option specified.") do
|
839
|
+
bm = Benchmarker.new(colorize: true)
|
840
|
+
ok {bm.__send__(:colorize?)} == true
|
841
|
+
capture_sio do
|
842
|
+
ok {bm.__send__(:colorize?)} == true
|
843
|
+
end
|
844
|
+
end
|
845
|
+
- spec("[!e0gcz] returns false if '-C' option specified.") do
|
846
|
+
bm = Benchmarker.new(colorize: false)
|
847
|
+
ok {bm.__send__(:colorize?)} == false
|
848
|
+
capture_sio do
|
849
|
+
ok {bm.__send__(:colorize?)} == false
|
850
|
+
end
|
851
|
+
end
|
852
|
+
- spec("[!6v90d] returns result of `Color.colorize?` if neither '-c' nor '-C' specified.") do
|
853
|
+
bm = Benchmarker.new()
|
854
|
+
ok {bm.__send__(:colorize?)} == true
|
855
|
+
capture_sio do
|
856
|
+
ok {bm.__send__(:colorize?)} == false
|
857
|
+
end
|
858
|
+
end
|
859
|
+
end
|
860
|
+
|
414
861
|
end
|
415
862
|
|
416
|
-
|
417
|
-
|
418
|
-
|
863
|
+
|
864
|
+
+ topic(Benchmarker::Scope) do
|
865
|
+
|
866
|
+
fixture :bm do
|
867
|
+
Benchmarker::Benchmark.new()
|
419
868
|
end
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
ok {@task1.total} == 4.0
|
424
|
-
ok {@task1.real } == 4.5
|
869
|
+
|
870
|
+
fixture :scope do |bm|
|
871
|
+
Benchmarker::Scope.new(bm)
|
425
872
|
end
|
426
|
-
end
|
427
873
|
|
428
|
-
|
429
|
-
spec
|
430
|
-
|
874
|
+
+ topic('#task()') do
|
875
|
+
- spec("[!j6pmr] creates new task object.") do |scope|
|
876
|
+
task = scope.task "name1", tag: "abc" do end
|
877
|
+
ok {task}.is_a?(Benchmarker::Task)
|
878
|
+
ok {task.name} == "name1"
|
879
|
+
ok {task.tag} == "abc"
|
880
|
+
end
|
881
|
+
- spec("[!kh7r9] define empty-loop task if name is nil.") do |scope|
|
882
|
+
task = scope.task nil do end
|
883
|
+
ok {task}.is_a?(Benchmarker::Task)
|
884
|
+
ok {task.name} == nil
|
885
|
+
end
|
886
|
+
+ case_when("[!843ju] when code argument provided...") do
|
887
|
+
- spec("[!bwfak] code argument and block argument are exclusive.") do |scope|
|
888
|
+
pr = proc { scope.task "foo", "x = 1+1" do nil end }
|
889
|
+
ok {pr}.raise?(Benchmarker::TaskError, "task(\"foo\"): cannot accept String argument when block argument given.")
|
890
|
+
end
|
891
|
+
- spec("[!4dm9q] generates block argument if code argument passed.") do |scope|
|
892
|
+
x = 0
|
893
|
+
task = scope.task "foo", "x += 1", binding()
|
894
|
+
ok {task.instance_eval{@block}}.is_a?(Proc)
|
895
|
+
task.instance_eval{@block}.call()
|
896
|
+
ok {x} == 100
|
897
|
+
end
|
898
|
+
end
|
431
899
|
end
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
900
|
+
|
901
|
+
+ topic('#empty_task()') do
|
902
|
+
- spec("[!ycoch] creates new empty-loop task object.") do |scope|
|
903
|
+
task = scope.empty_task do end
|
904
|
+
ok {task}.is_a?(Benchmarker::Task)
|
905
|
+
ok {task.name} == nil
|
906
|
+
end
|
437
907
|
end
|
438
|
-
end
|
439
908
|
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
t = klass.average([@task1, @task2])
|
449
|
-
ok {t.label} == @task1.label
|
450
|
-
not_ok {t.label}.same?(@task1)
|
451
|
-
end
|
452
|
-
spec "returns averaged task." do
|
453
|
-
t = klass.average([@task1, @task2, @task1, @task2])
|
454
|
-
ok {t.user } == (@task1.user + @task2.user ) / 2
|
455
|
-
ok {t.sys } == (@task1.sys + @task2.sys ) / 2
|
456
|
-
ok {t.total} == (@task1.total + @task2.total) / 2
|
457
|
-
ok {t.real } == (@task1.real + @task2.real ) / 2
|
909
|
+
+ topic('#before()') do
|
910
|
+
- spec("[!2ir4q] defines 'before' hook.") do |scope, bm|
|
911
|
+
called = false
|
912
|
+
scope.before do called = true end
|
913
|
+
ok {called} == false
|
914
|
+
bm.__send__(:call_hook, :before)
|
915
|
+
ok {called} == true
|
916
|
+
end
|
458
917
|
end
|
459
|
-
end
|
460
918
|
|
461
|
-
|
919
|
+
+ topic('#after()') do
|
920
|
+
- spec("[!05up6] defines 'after' hook.") do |scope, bm|
|
921
|
+
called = false
|
922
|
+
scope.after do called = true end
|
923
|
+
ok {called} == false
|
924
|
+
bm.__send__(:call_hook, :after)
|
925
|
+
ok {called} == true
|
926
|
+
end
|
927
|
+
end
|
462
928
|
|
929
|
+
+ topic('#before_all()') do
|
930
|
+
- spec("[!1oier] defines 'before_all' hook.") do |scope, bm|
|
931
|
+
called = false
|
932
|
+
scope.before_all do called = true end
|
933
|
+
ok {called} == false
|
934
|
+
bm.__send__(:call_hook, :before_all)
|
935
|
+
ok {called} == true
|
936
|
+
end
|
937
|
+
end
|
463
938
|
|
464
|
-
|
465
|
-
|
939
|
+
+ topic('#after_all()') do
|
940
|
+
- spec("[!z7xop] defines 'after_all' hook.") do |scope, bm|
|
941
|
+
called = false
|
942
|
+
scope.after_all do called = true end
|
943
|
+
ok {called} == false
|
944
|
+
bm.__send__(:call_hook, :after_all)
|
945
|
+
ok {called} == true
|
946
|
+
end
|
947
|
+
end
|
466
948
|
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
949
|
+
+ topic('#validate()') do
|
950
|
+
- spec("[!q2aev] defines validator.") do
|
951
|
+
bm = Benchmarker::Benchmark.new()
|
952
|
+
scope = Benchmarker::Scope.new(bm)
|
953
|
+
ok {bm.instance_eval{@hooks[:validate]}} == nil
|
954
|
+
scope.validate do |ret| end
|
955
|
+
ok {bm.instance_eval{@hooks[:validate]}} != nil
|
956
|
+
ok {bm.instance_eval{@hooks[:validate]}}.is_a?(Proc)
|
957
|
+
end
|
958
|
+
end
|
471
959
|
|
472
|
-
|
473
|
-
spec
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
960
|
+
+ topic('#assert()') do
|
961
|
+
- spec("[!a0c7e] do nothing if assertion succeeded.") do |scope|
|
962
|
+
capture_sio do
|
963
|
+
pr = proc { scope.assert 1+1 == 2, "1+1 is 2" }
|
964
|
+
ok {pr}.NOT.raise?
|
965
|
+
end
|
966
|
+
end
|
967
|
+
- spec("[!5vmbc] raises error if assertion failed.") do |scope|
|
968
|
+
capture_sio do
|
969
|
+
pr = proc { scope.assert 1+1 == 1, "1+1 is not 1" }
|
970
|
+
ok {pr}.raise?(Benchmarker::ValidationFailed, "1+1 is not 1")
|
971
|
+
end
|
972
|
+
end
|
973
|
+
- spec("[!7vt5l] puts newline if assertion failed.") do |scope|
|
974
|
+
sout, serr = capture_sio do
|
975
|
+
pr = proc { scope.assert true, "" }
|
976
|
+
ok {pr}.NOT.raise?(Benchmarker::ValidationFailed)
|
977
|
+
end
|
978
|
+
ok {sout} == ""
|
979
|
+
#
|
980
|
+
sout, serr = capture_sio do
|
981
|
+
pr = proc { scope.assert false, "" }
|
982
|
+
ok {pr}.raise?(Benchmarker::ValidationFailed)
|
983
|
+
end
|
984
|
+
ok {sout} == "\n"
|
985
|
+
end
|
986
|
+
- spec("[!mhw59] makes error backtrace compact.") do |scope|
|
987
|
+
capture_sio do
|
988
|
+
pr = proc { scope.assert false, "" }
|
989
|
+
ok {pr}.raise?(Benchmarker::ValidationFailed) do |exc|
|
990
|
+
ok {exc.backtrace}.all? {|x| x !~ /benchmarker\.rb/ }
|
991
|
+
end
|
992
|
+
end
|
993
|
+
end
|
479
994
|
end
|
480
|
-
end
|
481
995
|
|
482
|
-
|
483
|
-
spec
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
996
|
+
+ topic('#assert_eq()') do
|
997
|
+
- spec("[!8m6bh] do nothing if ectual == expected.") do |scope|
|
998
|
+
capture_sio do
|
999
|
+
pr = proc { scope.assert_eq 1+1, 2 }
|
1000
|
+
ok {pr}.NOT.raise?
|
1001
|
+
end
|
1002
|
+
end
|
1003
|
+
- spec("[!f9ey6] raises error unless actual == expected.") do |scope|
|
1004
|
+
capture_sio do
|
1005
|
+
pr = proc { scope.assert_eq 'a'*3, 'aa' }
|
1006
|
+
ok {pr}.raise?(Benchmarker::ValidationFailed, '"aaa" == "aa": failed.')
|
489
1007
|
end
|
490
|
-
r.write("Kyon\n")
|
491
1008
|
end
|
492
|
-
ok {sout} == "Haruhi\nKyon\n"
|
493
|
-
ok {serr} == "Sasaki\n"
|
494
1009
|
end
|
1010
|
+
|
495
1011
|
end
|
496
1012
|
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
1013
|
+
|
1014
|
+
+ topic(Benchmarker::Task) do
|
1015
|
+
|
1016
|
+
+ topic('#invoke()') do
|
1017
|
+
+ case_when("[!s2f6v] when task block is build from repeated code...") do
|
1018
|
+
- spec("[!i2r8o] error when number of loop is less than 100.") do
|
1019
|
+
capture_sio do
|
1020
|
+
pr = proc do
|
1021
|
+
Benchmarker.scope(loop: 100) do
|
1022
|
+
task "foo", "x = 1+1"
|
1023
|
+
end
|
1024
|
+
end
|
1025
|
+
ok {pr}.NOT.raise?
|
1026
|
+
#
|
1027
|
+
pr = proc do
|
1028
|
+
Benchmarker.scope(loop: 99) do
|
1029
|
+
task "foo", "x = 1+1"
|
1030
|
+
end
|
1031
|
+
end
|
1032
|
+
ok {pr}.raise?(Benchmarker::TaskError, 'task("foo"): number of loop (=99) should be >= 100, but not.')
|
1033
|
+
end
|
1034
|
+
end
|
1035
|
+
- spec("[!kzno6] error when number of loop is not a multiple of 100.") do
|
1036
|
+
capture_sio do
|
1037
|
+
pr = proc do
|
1038
|
+
Benchmarker.scope(loop: 200) do
|
1039
|
+
task "foo", "x = 1+1"
|
1040
|
+
end
|
1041
|
+
end
|
1042
|
+
ok {pr}.NOT.raise?
|
1043
|
+
#
|
1044
|
+
pr = proc do
|
1045
|
+
Benchmarker.scope(loop: 250) do
|
1046
|
+
task "foo", "x = 1+1"
|
1047
|
+
end
|
1048
|
+
end
|
1049
|
+
ok {pr}.raise?(Benchmarker::TaskError, 'task("foo"): number of loop (=250) should be a multiple of 100, but not.')
|
1050
|
+
end
|
1051
|
+
end
|
1052
|
+
- spec("[!gbukv] changes number of loop to 1/100.") do
|
1053
|
+
capture_sio do
|
1054
|
+
called = 0
|
1055
|
+
Benchmarker.scope(loop: 200) do
|
1056
|
+
task "foo", "called +=1", binding()
|
1057
|
+
end
|
1058
|
+
ok {called} == 200
|
1059
|
+
end
|
1060
|
+
end
|
1061
|
+
end
|
1062
|
+
- spec("[!frq25] kicks GC before calling task block.") do
|
1063
|
+
capture_sio do
|
1064
|
+
rec = recorder()
|
1065
|
+
rec.record_method(GC, :start)
|
1066
|
+
called = false
|
1067
|
+
Benchmarker.scope() do
|
1068
|
+
task "foo" do called = true end
|
1069
|
+
end
|
1070
|
+
ok {called} == true
|
1071
|
+
ok {rec[0].obj} == GC
|
1072
|
+
ok {rec[0].name} == :start
|
1073
|
+
end
|
1074
|
+
end
|
1075
|
+
- spec("[!tgql6] invokes block N times.") do
|
1076
|
+
cnt = 0
|
1077
|
+
task = Benchmarker::Task.new("name1") do cnt += 1 end
|
1078
|
+
task.invoke(3)
|
1079
|
+
ok {cnt} == 3
|
1080
|
+
end
|
1081
|
+
- spec("[!9e5pr] returns TimeSet object.") do
|
1082
|
+
task = Benchmarker::Task.new("name1") do nil end
|
1083
|
+
ret = task.invoke()
|
1084
|
+
ok {ret}.is_a?(Benchmarker::TimeSet)
|
1085
|
+
end
|
1086
|
+
- spec("[!zw4kt] yields validator with result value of block.") do
|
1087
|
+
task = Benchmarker::Task.new("name1", tag: "curr") do 234 end
|
1088
|
+
args = nil
|
1089
|
+
task.invoke() do |*a| args = a end
|
1090
|
+
ok {args} == [234, "name1", "curr"]
|
1091
|
+
end
|
504
1092
|
end
|
1093
|
+
|
505
1094
|
end
|
506
1095
|
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
1096
|
+
|
1097
|
+
+ topic(Benchmarker::TimeSet) do
|
1098
|
+
|
1099
|
+
+ topic('#-()') do
|
1100
|
+
- spec("[!cpwgf] returns new TimeSet object.") do
|
1101
|
+
t1 = Benchmarker::TimeSet.new(2.0, 3.0, 4.0, 5.0)
|
1102
|
+
t2 = Benchmarker::TimeSet.new(2.5, 3.5, 5.0, 5.25)
|
1103
|
+
t3 = t2 - t1
|
1104
|
+
ok {t3} != t1
|
1105
|
+
ok {t3} != t2
|
1106
|
+
ok {t3.user} == 0.5
|
1107
|
+
ok {t3.sys} == 0.5
|
1108
|
+
ok {t3.total} == 1.0
|
1109
|
+
ok {t3.real} == 0.25
|
1110
|
+
end
|
511
1111
|
end
|
512
|
-
|
513
|
-
|
1112
|
+
|
1113
|
+
+ topic('#div()') do
|
1114
|
+
- spec("[!4o9ns] returns new TimeSet object which values are divided by n.") do
|
1115
|
+
t1 = Benchmarker::TimeSet.new(2.5, 3.5, 5.0, 5.25)
|
1116
|
+
t2 = t1.div(100)
|
1117
|
+
ok {t2.user } == 0.025
|
1118
|
+
ok {t2.sys } == 0.035
|
1119
|
+
ok {t2.total} == 0.050
|
1120
|
+
ok {t2.real } == 0.0525
|
1121
|
+
end
|
514
1122
|
end
|
1123
|
+
|
515
1124
|
end
|
516
1125
|
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
1126
|
+
|
1127
|
+
+ topic(Benchmarker::Result) do
|
1128
|
+
|
1129
|
+
fixture :r do
|
1130
|
+
Benchmarker::Result.new
|
521
1131
|
end
|
522
|
-
|
523
|
-
|
1132
|
+
|
1133
|
+
+ topic('#add()') do
|
1134
|
+
- spec("[!thyms] adds timeset and returns self.") do |r|
|
1135
|
+
t = Benchmarker::TimeSet.new(1.0, 2.0, 3.0, 4.0)
|
1136
|
+
r.add(t)
|
1137
|
+
ok {r[0]} == t
|
1138
|
+
end
|
524
1139
|
end
|
525
|
-
|
526
|
-
|
1140
|
+
|
1141
|
+
+ topic('#clear()') do
|
1142
|
+
- spec("[!fxrn6] clears timeset array.") do |r|
|
1143
|
+
ok {r.length} == 0
|
1144
|
+
r.add(Benchmarker::TimeSet.new(1.0, 2.0, 3.0, 4.0))
|
1145
|
+
r.add(Benchmarker::TimeSet.new(0.0, 0.0, 0.0, 0.0))
|
1146
|
+
ok {r.length} == 2
|
1147
|
+
r.clear()
|
1148
|
+
ok {r.length} == 0
|
1149
|
+
end
|
527
1150
|
end
|
528
|
-
end
|
529
1151
|
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
1152
|
+
+ topic('#skipped?') do
|
1153
|
+
- spec("[!bvzk9] returns true if reason has set, or returns false.") do |r|
|
1154
|
+
ok {r.skipped?} == false
|
1155
|
+
r.skipped = "why skipped"
|
1156
|
+
ok {r.skipped?} == true
|
1157
|
+
end
|
534
1158
|
end
|
535
|
-
|
536
|
-
|
1159
|
+
|
1160
|
+
+ topic('#remove_minmax()') do
|
1161
|
+
- spec("[!b55zh] removes best and worst timeset and returns them.") do |r|
|
1162
|
+
klass = Benchmarker::TimeSet
|
1163
|
+
arr = [
|
1164
|
+
klass.new(0.1, 0.1, 0.1, 0.3),
|
1165
|
+
klass.new(0.1, 0.1, 0.1, 0.1),
|
1166
|
+
klass.new(0.1, 0.1, 0.1, 0.4),
|
1167
|
+
klass.new(0.1, 0.1, 0.1, 0.5),
|
1168
|
+
klass.new(0.1, 0.1, 0.1, 0.9),
|
1169
|
+
klass.new(0.1, 0.1, 0.1, 0.2),
|
1170
|
+
klass.new(0.1, 0.1, 0.1, 0.6),
|
1171
|
+
klass.new(0.1, 0.1, 0.1, 0.8),
|
1172
|
+
klass.new(0.1, 0.1, 0.1, 0.7),
|
1173
|
+
]
|
1174
|
+
#
|
1175
|
+
r1 = Benchmarker::Result.new
|
1176
|
+
arr.each {|t| r1.add(t) }
|
1177
|
+
removed = r1.remove_minmax(1)
|
1178
|
+
ok {removed} == [
|
1179
|
+
[0.1, 2, 0.9, 5],
|
1180
|
+
]
|
1181
|
+
vals = []; r1.each {|t| vals << t.real }
|
1182
|
+
ok {vals} == [0.3, 0.4, 0.5, 0.2, 0.6, 0.8, 0.7]
|
1183
|
+
#
|
1184
|
+
r2 = Benchmarker::Result.new
|
1185
|
+
arr.each {|t| r2.add(t) }
|
1186
|
+
removed = r2.remove_minmax(2)
|
1187
|
+
ok {removed} == [
|
1188
|
+
[0.1, 2, 0.9, 5],
|
1189
|
+
[0.2, 6, 0.8, 8],
|
1190
|
+
]
|
1191
|
+
vals = []; r2.each {|t| vals << t.real }
|
1192
|
+
ok {vals} == [0.3, 0.4, 0.5, 0.6, 0.7]
|
1193
|
+
end
|
537
1194
|
end
|
538
|
-
|
539
|
-
|
1195
|
+
|
1196
|
+
+ topic('#calc_average()') do
|
1197
|
+
- spec("[!b91w3] returns average of timeddata.") do |r|
|
1198
|
+
klass = Benchmarker::TimeSet
|
1199
|
+
arr = [
|
1200
|
+
klass.new(0.1, 0.1, 0.3, 0.3),
|
1201
|
+
klass.new(0.2, 0.1, 0.3, 0.1),
|
1202
|
+
klass.new(0.3, 0.1, 0.3, 0.4),
|
1203
|
+
klass.new(0.4, 0.1, 0.3, 0.5),
|
1204
|
+
klass.new(0.5, 0.1, 0.3, 0.9),
|
1205
|
+
klass.new(0.6, 0.1, 0.3, 0.2),
|
1206
|
+
klass.new(0.7, 0.1, 0.3, 0.6),
|
1207
|
+
klass.new(0.8, 0.1, 0.3, 0.8),
|
1208
|
+
klass.new(0.9, 0.1, 0.3, 0.7),
|
1209
|
+
]
|
1210
|
+
arr.each {|t| r.add(t) }
|
1211
|
+
t = r.calc_average()
|
1212
|
+
ok {t}.is_a?(klass)
|
1213
|
+
ok {t.user }.in_delta?(0.5, 0.000000001)
|
1214
|
+
ok {t.sys }.in_delta?(0.1, 0.000000001)
|
1215
|
+
ok {t.total}.in_delta?(0.3, 0.000000001)
|
1216
|
+
ok {t.real }.in_delta?(0.5, 0.000000001)
|
1217
|
+
end
|
1218
|
+
|
540
1219
|
end
|
1220
|
+
|
541
1221
|
end
|
542
1222
|
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
ok {ret}.same?(@r)
|
1223
|
+
|
1224
|
+
+ topic(Benchmarker::Color) do
|
1225
|
+
|
1226
|
+
+ topic('.colorize?()') do
|
1227
|
+
- spec("[!fc741] returns true if stdout is a tty, else returns false.") do
|
1228
|
+
ok {Benchmarker::Color.colorize?} == true
|
1229
|
+
capture_sio do
|
1230
|
+
ok {Benchmarker::Color.colorize?} == false
|
1231
|
+
end
|
1232
|
+
end
|
554
1233
|
end
|
1234
|
+
|
555
1235
|
end
|
556
1236
|
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
1237
|
+
|
1238
|
+
+ topic(Benchmarker::Misc) do
|
1239
|
+
|
1240
|
+
+ topic('.environment_info()') do
|
1241
|
+
- spec("[!w1xfa] returns environment info in key-value list.") do
|
1242
|
+
arr = Benchmarker::Misc.environment_info()
|
1243
|
+
ok {arr}.is_a?(Array)
|
1244
|
+
ok {arr[0][0]} == "benchmarker"
|
1245
|
+
ok {arr[1][0]} == "ruby engine"
|
1246
|
+
ok {arr[2][0]} == "ruby version"
|
1247
|
+
ok {arr[3][0]} == "ruby platform"
|
1248
|
+
ok {arr[4][0]} == "ruby path"
|
1249
|
+
ok {arr[5][0]} == "compiler"
|
1250
|
+
ok {arr[6][0]} == "os name"
|
1251
|
+
ok {arr[7][0]} == "cpu model"
|
1252
|
+
ok {arr[8]} == nil
|
1253
|
+
end
|
568
1254
|
end
|
569
|
-
end
|
570
1255
|
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
@r.instance_variable_set('@format_label', "%-12s")
|
577
|
-
@r.report_task_label("Sasakisan")
|
578
|
-
ok {@buf} == "Sasakisan "
|
1256
|
+
+ topic('.os_name()') do
|
1257
|
+
- spec("[!83vww] returns string representing os name.") do
|
1258
|
+
str = Benchmarker::Misc.os_name()
|
1259
|
+
ok {str}.is_a?(String)
|
1260
|
+
end
|
579
1261
|
end
|
580
|
-
|
581
|
-
|
1262
|
+
|
1263
|
+
+ topic('.cpu_model()') do
|
1264
|
+
- spec("[!6ncgq] returns string representing cpu model.") do
|
1265
|
+
str = Benchmarker::Misc.cpu_model()
|
1266
|
+
ok {str}.is_a?(String)
|
1267
|
+
end
|
582
1268
|
end
|
1269
|
+
|
583
1270
|
end
|
584
1271
|
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
1272
|
+
|
1273
|
+
+ topic(Benchmarker::OptionParser) do
|
1274
|
+
|
1275
|
+
fixture :p do
|
1276
|
+
Benchmarker::OptionParser.new("hvq", "wnixoF", "I")
|
589
1277
|
end
|
590
|
-
|
591
|
-
|
1278
|
+
|
1279
|
+
+ topic('#parse()') do
|
1280
|
+
- spec("[!2gq7g] returns options and keyvals.")do |p|
|
1281
|
+
argv = ['-hqn100', '-i', '5', '-I', '--help', '--foo=bar']
|
1282
|
+
options, keyvals = p.parse(argv)
|
1283
|
+
ok {options} == {'h'=>true, 'q'=>true, 'n'=>'100', 'i'=>'5', 'I'=>true}
|
1284
|
+
ok {keyvals} == {'help'=>true, 'foo'=>'bar'}
|
1285
|
+
ok {argv} == []
|
1286
|
+
end
|
1287
|
+
- spec("[!ulfpu] stops parsing when '--' found.") do |p|
|
1288
|
+
argv = ['-h', '--', '-i', '5']
|
1289
|
+
options, keyvals = p.parse(argv)
|
1290
|
+
ok {options} == {'h'=>true}
|
1291
|
+
ok {keyvals} == {}
|
1292
|
+
ok {argv} == ['-i', '5']
|
1293
|
+
end
|
1294
|
+
- spec("[!8f085] regards '--long=option' as key-value.") do |p|
|
1295
|
+
argv = ['--foo=bar', '--baz']
|
1296
|
+
options, keyvals = p.parse(argv)
|
1297
|
+
ok {options} == {}
|
1298
|
+
ok {keyvals} == {'foo'=>'bar', 'baz'=>true}
|
1299
|
+
ok {argv} == []
|
1300
|
+
end
|
1301
|
+
- spec("[!dkq1u] parses short options.") do |p|
|
1302
|
+
argv = ['-h', '-qn100', '-vi', '10', '-x', '2']
|
1303
|
+
options, keyvals = p.parse(argv)
|
1304
|
+
ok {options} == {'h'=>true, 'q'=>true, 'n'=>'100', 'v'=>true, 'i'=>'10', 'x'=>'2'}
|
1305
|
+
ok {keyvals} == {}
|
1306
|
+
ok {argv} == []
|
1307
|
+
end
|
1308
|
+
- spec("[!8xqla] error when required argument is not provided.") do |p|
|
1309
|
+
argv = ['-qn']
|
1310
|
+
a_ = nil
|
1311
|
+
p.parse(argv) do |*a| a_ = a end
|
1312
|
+
ok {a_} == ["-n: argument required."]
|
1313
|
+
end
|
1314
|
+
- spec("[!tmx6o] error when option is unknown.") do |p|
|
1315
|
+
argv = ['-hz']
|
1316
|
+
a_ = nil
|
1317
|
+
p.parse(argv) do |*a| a_ = a end
|
1318
|
+
ok {a_} == ["-z: unknown option."]
|
1319
|
+
end
|
592
1320
|
end
|
593
|
-
end
|
594
1321
|
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
1322
|
+
+ topic('.parse_options()') do
|
1323
|
+
- spec("[!v19y5] converts option argument into integer if necessary.") do
|
1324
|
+
argv = ['-h', '-n100', '-vi', '10', '-x', '2', '-I5000']
|
1325
|
+
options, keyvals = Benchmarker::OptionParser.parse_options(argv)
|
1326
|
+
ok {options} == {"h"=>true, "n"=>100, "v"=>true, "i"=>10, "x"=>2, "I"=>5000}
|
1327
|
+
ok {keyvals} == {}
|
1328
|
+
end
|
1329
|
+
- spec("[!frfz2] yields error message when argument of '-n/i/x/I' is not an integer.") do
|
1330
|
+
err = nil
|
1331
|
+
Benchmarker::OptionParser.parse_options(['-nxx']) do |s| err = s end
|
1332
|
+
ok {err} == "-n xx: integer expected."
|
1333
|
+
#
|
1334
|
+
err = nil
|
1335
|
+
Benchmarker::OptionParser.parse_options(['-iyy']) do |s| err = s end
|
1336
|
+
ok {err} == "-i yy: integer expected."
|
1337
|
+
#
|
1338
|
+
err = nil
|
1339
|
+
Benchmarker::OptionParser.parse_options(['-xzz']) do |s| err = s end
|
1340
|
+
ok {err} == "-x zz: integer expected."
|
1341
|
+
#
|
1342
|
+
err = nil
|
1343
|
+
Benchmarker::OptionParser.parse_options(['-Izz']) do |s| err = s end
|
1344
|
+
ok {err} == "-Izz: integer expected."
|
1345
|
+
end
|
1346
|
+
- spec("[!nz15w] convers '-s' option value into number (integer or float).") do
|
1347
|
+
options, _ = Benchmarker::OptionParser.parse_options(['-s', '123'])
|
1348
|
+
ok {options} == {"s"=>123}
|
1349
|
+
options, _ = Benchmarker::OptionParser.parse_options(['-s', '0.5'])
|
1350
|
+
ok {options} == {"s"=>0.5}
|
1351
|
+
end
|
1352
|
+
- spec("[!3x1m7] yields error message when argument of '-s' is not a number.") do
|
1353
|
+
err = nil
|
1354
|
+
Benchmarker::OptionParser.parse_options(['-s', 'aa']) do |s| err = s end
|
1355
|
+
ok {err} == "-s aa: number expected."
|
1356
|
+
end
|
1357
|
+
- spec("[!emavm] yields error message when argumetn of '-F' option is invalid.") do
|
1358
|
+
err = nil
|
1359
|
+
Benchmarker::OptionParser.parse_options(['-F', 'xyz']) do |s| err = s end
|
1360
|
+
ok {err} == "-F xyz: invalid filter (expected operator is '=' or '!=')."
|
1361
|
+
#
|
1362
|
+
err = nil
|
1363
|
+
Benchmarker::OptionParser.parse_options(['-F', 'name=xyz']) do |s| err = s end
|
1364
|
+
ok {err} == "-F name=xyz: expected 'task=...' or 'tag=...'."
|
1365
|
+
end
|
599
1366
|
end
|
600
|
-
|
601
|
-
|
1367
|
+
|
1368
|
+
+ topic('.help_message()') do
|
1369
|
+
- spec("[!jnm2w] returns help message.") do
|
1370
|
+
msg = Benchmarker::OptionParser.help_message("bench.rb")
|
1371
|
+
ok {msg} == <<'END'
|
1372
|
+
Usage: bench.rb [<options>]
|
1373
|
+
-h, --help : help message
|
1374
|
+
-v : print Benchmarker version
|
1375
|
+
-w <N> : width of task name (default: 30)
|
1376
|
+
-n <N> : loop N times in each benchmark (default: 1)
|
1377
|
+
-i <N> : iterates all benchmark tasks N times (default: 1)
|
1378
|
+
-x <N> : ignore worst N results and best N results (default: 0)
|
1379
|
+
-I[<N>] : print inverse number (= N/sec) (default: same as '-n')
|
1380
|
+
-o <file> : output file in JSON format
|
1381
|
+
-q : quiet a little (suppress output of each iteration)
|
1382
|
+
-c : enable colorized output
|
1383
|
+
-C : disable colorized output
|
1384
|
+
-s <N> : sleep N seconds after each benchmark task
|
1385
|
+
-S : print sample code
|
1386
|
+
-F task=<...> : filter benchmark task by name (operator: '=' or '!=')
|
1387
|
+
-F tag=<...> : filter benchmark task by tag (operator: '=' or '!=')
|
1388
|
+
--<key>[=<val>]: define global variable `$opt_<key> = "<val>"`
|
1389
|
+
END
|
1390
|
+
end
|
602
1391
|
end
|
1392
|
+
|
603
1393
|
end
|
604
1394
|
|
605
|
-
end
|
606
1395
|
|
1396
|
+
+ topic(Benchmarker) do
|
607
1397
|
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
def before
|
612
|
-
@out = ""
|
613
|
-
@r = Benchmarker::Reporter.new(:out=>@out)
|
614
|
-
@stats = Benchmarker::Stats.new(@r)
|
615
|
-
#
|
616
|
-
@tasks = []
|
617
|
-
sos = proc do |label, user, sys, total, real|
|
618
|
-
t = Benchmarker::TASK.new(label)
|
619
|
-
t.user, t.sys, t.total, t.real = user, sys, total, real
|
620
|
-
@tasks << t
|
621
|
-
end
|
622
|
-
sos.call("Haruhi", 11.1, 0.2, 11.3, 11.5)
|
623
|
-
sos.call("Mikuru", 14.1, 0.2, 14.3, 14.5)
|
624
|
-
sos.call("Yuki", 10.1, 0.2, 10.3, 10.5)
|
625
|
-
sos.call("Itsuki", 12.1, 0.2, 12.3, 12.5)
|
626
|
-
sos.call("Kyon", 13.1, 0.2, 13.3, 13.5)
|
627
|
-
end
|
1398
|
+
after do
|
1399
|
+
Benchmarker::OPTIONS.clear()
|
1400
|
+
end
|
628
1401
|
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
1402
|
+
+ topic('.parse_cmdopts()') do
|
1403
|
+
- spec("[!348ip] parses command-line options.") do
|
1404
|
+
ok {Benchmarker::OPTIONS} == {}
|
1405
|
+
argv = "-q -n 1000 -i10 -x2 -I -o tmp.json".split()
|
1406
|
+
options, keyvals = Benchmarker.parse_cmdopts(argv)
|
1407
|
+
ok {options} == {'q'=>true, 'n'=>1000, 'i'=>10, 'x'=>2, 'I'=>true, 'o'=>"tmp.json"}
|
1408
|
+
ok {keyvals} == {}
|
1409
|
+
end
|
1410
|
+
- spec("[!snqxo] exits with status code 1 if error in command option.") do
|
1411
|
+
argv = ["-n abc"]
|
1412
|
+
sout, serr = capture_sio do
|
1413
|
+
pr = proc { Benchmarker.parse_cmdopts(argv) }
|
1414
|
+
ok {pr}.raise?(SystemExit) do |exc|
|
1415
|
+
ok {exc.status} == 1
|
1416
|
+
end
|
1417
|
+
end
|
1418
|
+
ok {serr} == "-n abc: integer expected.\n"
|
1419
|
+
ok {sout} == ""
|
1420
|
+
end
|
1421
|
+
- spec("[!p3b93] prints help message if '-h' or '--help' option specified.") do
|
1422
|
+
["-h", "--help"].each do |arg|
|
1423
|
+
sout, serr = capture_sio do
|
1424
|
+
pr = proc { Benchmarker.parse_cmdopts([arg]) }
|
1425
|
+
ok {pr}.raise?(SystemExit) do |exc|
|
1426
|
+
ok {exc.status} == 0
|
1427
|
+
end
|
1428
|
+
end
|
1429
|
+
ok {serr} == ""
|
1430
|
+
ok {sout} =~ /^Usage: \S+ \[<options>\]$/
|
1431
|
+
ok {sout} =~ /^ -h, --help : help message$/
|
1432
|
+
end
|
1433
|
+
end
|
1434
|
+
- spec("[!iaryj] prints version number if '-v' option specified.") do
|
1435
|
+
argv = ["-v"]
|
1436
|
+
sout, serr = capture_sio do
|
1437
|
+
pr = proc { Benchmarker.parse_cmdopts(argv) }
|
1438
|
+
ok {pr}.raise?(SystemExit) do |exc|
|
1439
|
+
ok {exc.status} == 0
|
1440
|
+
end
|
1441
|
+
end
|
1442
|
+
ok {serr} == ""
|
1443
|
+
ok {sout} == Benchmarker::VERSION + "\n"
|
1444
|
+
end
|
1445
|
+
- spec("[!nrxsb] prints sample code if '-S' option specified.") do
|
1446
|
+
argv = ["-S"]
|
1447
|
+
sout, serr = capture_sio do
|
1448
|
+
pr = proc { Benchmarker.parse_cmdopts(argv) }
|
1449
|
+
ok {pr}.raise?(SystemExit) do |exc|
|
1450
|
+
ok {exc.status} == 0
|
1451
|
+
end
|
1452
|
+
end
|
1453
|
+
ok {serr} == ""
|
1454
|
+
ok {sout} == Benchmarker::Misc.sample_code()
|
1455
|
+
end
|
1456
|
+
- spec("[!s7y6x] keeps command-line options in order to overwirte existing options.") do
|
1457
|
+
ok {Benchmarker::OPTIONS} == {}
|
1458
|
+
argv = "-q -n 1000 -i10 -x2 -I -o tmp.json".split()
|
1459
|
+
Benchmarker.parse_cmdopts(argv)
|
1460
|
+
ok {Benchmarker::OPTIONS} == {
|
1461
|
+
:quiet=>true, :loop=>1000, :iter=>10, :extra=>2,
|
1462
|
+
:inverse=>true, :outfile=>"tmp.json",
|
1463
|
+
}
|
1464
|
+
end
|
1465
|
+
- spec("[!nexi8] option '-w' specifies task name width.") do
|
1466
|
+
ok {Benchmarker::OPTIONS} == {}
|
1467
|
+
Benchmarker.parse_cmdopts(['-w', '10'])
|
1468
|
+
ok {Benchmarker::OPTIONS} == {width: 10}
|
1469
|
+
sout, serr = capture_sio do
|
1470
|
+
Benchmarker.scope(width: 20) do
|
1471
|
+
task "foo" do nil end
|
1472
|
+
end
|
1473
|
+
end
|
1474
|
+
ok {sout} =~ /^foo 0.0000/
|
1475
|
+
end
|
1476
|
+
- spec("[!raki9] option '-n' specifies count of loop.") do
|
1477
|
+
ok {Benchmarker::OPTIONS} == {}
|
1478
|
+
Benchmarker.parse_cmdopts(['-n', '17'])
|
1479
|
+
ok {Benchmarker::OPTIONS} == {loop: 17}
|
1480
|
+
count = 0
|
1481
|
+
sout, serr = capture_sio do
|
1482
|
+
Benchmarker.scope(width: 20) do
|
1483
|
+
task "foo" do count += 1 end
|
1484
|
+
end
|
1485
|
+
end
|
1486
|
+
ok {count} == 17
|
1487
|
+
end
|
1488
|
+
- spec("[!mt7lw] option '-i' specifies number of iteration.") do
|
1489
|
+
ok {Benchmarker::OPTIONS} == {}
|
1490
|
+
Benchmarker.parse_cmdopts(['-i', '5'])
|
1491
|
+
ok {Benchmarker::OPTIONS} == {iter: 5}
|
1492
|
+
count = 0
|
1493
|
+
sout, serr = capture_sio do
|
1494
|
+
Benchmarker.scope(width: 20) do
|
1495
|
+
task "foo" do count += 1 end
|
1496
|
+
end
|
1497
|
+
end
|
1498
|
+
ok {sout} =~ /^## \(#5\)/
|
1499
|
+
ok {sout} !~ /^## \(#6\)/
|
1500
|
+
n = 0
|
1501
|
+
sout.scan(/^## \(#\d+\).*\nfoo +/) do n += 1 end
|
1502
|
+
ok {n} == 5
|
1503
|
+
ok {sout} !~ /^## Removed Min & Max/
|
1504
|
+
ok {sout} =~ /^## Average of 5 +user/
|
1505
|
+
end
|
1506
|
+
- spec("[!7f2k3] option '-x' specifies number of best/worst tasks removed.") do
|
1507
|
+
ok {Benchmarker::OPTIONS} == {}
|
1508
|
+
Benchmarker.parse_cmdopts(['-i', '5', '-x', '1'])
|
1509
|
+
ok {Benchmarker::OPTIONS} == {iter: 5, extra: 1}
|
1510
|
+
count = 0
|
1511
|
+
sout, serr = capture_sio do
|
1512
|
+
Benchmarker.scope(width: 20) do
|
1513
|
+
task "foo" do count += 1 end
|
1514
|
+
end
|
1515
|
+
end
|
1516
|
+
ok {sout} =~ /^## \(#7\)/
|
1517
|
+
ok {sout} !~ /^## \(#8\)/
|
1518
|
+
n = 0
|
1519
|
+
sout.scan(/^## \(#\d+\).*\nfoo +/) do n += 1 end
|
1520
|
+
ok {n} == 7
|
1521
|
+
ok {sout} =~ /^## Removed Min & Max/
|
1522
|
+
ok {sout} =~ /^## Average of 5 \(=7-2\*1\)/
|
1523
|
+
end
|
1524
|
+
- spec("[!r0439] option '-I' specifies inverse switch.") do
|
1525
|
+
ok {Benchmarker::OPTIONS} == {}
|
1526
|
+
Benchmarker.parse_cmdopts(['-I'])
|
1527
|
+
ok {Benchmarker::OPTIONS} == {inverse: true}
|
1528
|
+
sout, serr = capture_sio do
|
1529
|
+
fib = proc {|n| n <= 1 ? n : fib.call(n-1) + fib.call(n-2) }
|
1530
|
+
Benchmarker.scope(width: 20) do
|
1531
|
+
task "foo" do fib.call(15) end
|
1532
|
+
end
|
1533
|
+
end
|
1534
|
+
ok {sout} =~ /^## Ranking real times\/sec$/
|
1535
|
+
ok {sout} =~ /^foo +\d+\.\d+ \(100\.0%\) +\d+\.\d+$/
|
1536
|
+
end
|
1537
|
+
- spec("[!4c73x] option '-o' specifies outout JSON file.") do
|
1538
|
+
ok {Benchmarker::OPTIONS} == {}
|
1539
|
+
outfile = "tmp99.json"
|
1540
|
+
Benchmarker.parse_cmdopts(['-o', outfile])
|
1541
|
+
ok {Benchmarker::OPTIONS} == {outfile: outfile}
|
1542
|
+
at_exit { File.unlink outfile if File.exist?(outfile) }
|
1543
|
+
ok {outfile}.not_exist?
|
1544
|
+
sout, serr = capture_sio do
|
1545
|
+
Benchmarker.scope(width: 20) do
|
1546
|
+
task "foo" do nil end
|
1547
|
+
end
|
1548
|
+
end
|
1549
|
+
ok {outfile}.file_exist?
|
1550
|
+
end
|
1551
|
+
- spec("[!02ml5] option '-q' specifies quiet mode.") do
|
1552
|
+
ok {Benchmarker::OPTIONS} == {}
|
1553
|
+
Benchmarker.parse_cmdopts(['-q', '-i10', '-x1'])
|
1554
|
+
ok {Benchmarker::OPTIONS} == {quiet: true, iter: 10, extra: 1}
|
1555
|
+
count = 0
|
1556
|
+
sout, serr = capture_sio do
|
1557
|
+
Benchmarker.scope(width: 20) do
|
1558
|
+
task "foo" do count += 1 end
|
1559
|
+
end
|
1560
|
+
end
|
1561
|
+
ok {count} == 12
|
1562
|
+
ok {sout} !~ /^## \(#\d\)/
|
1563
|
+
ok {sout} =~ /^## Removed Min & Max/
|
1564
|
+
ok {sout} =~ /^## Average of 10 \(=12-2\*1\)/
|
1565
|
+
end
|
1566
|
+
- spec("[!e5hv0] option '-c' specifies colorize enabled.") do
|
1567
|
+
ok {Benchmarker::OPTIONS} == {}
|
1568
|
+
Benchmarker.parse_cmdopts(['-c'])
|
1569
|
+
ok {Benchmarker::OPTIONS} == {colorize: true}
|
1570
|
+
sout, serr = capture_sio(tty: false) do
|
1571
|
+
Benchmarker.scope() do
|
1572
|
+
task "foo" do nil end
|
1573
|
+
end
|
1574
|
+
end
|
1575
|
+
ok {sout} =~ /\e\[0;36m.*?\e\[0m/
|
1576
|
+
end
|
1577
|
+
- spec("[!e5hv0] option '-c' specifies colorize enabled.") do
|
1578
|
+
ok {Benchmarker::OPTIONS} == {}
|
1579
|
+
Benchmarker.parse_cmdopts(['-C'])
|
1580
|
+
ok {Benchmarker::OPTIONS} == {colorize: false}
|
1581
|
+
sout, serr = capture_sio(tty: true) do
|
1582
|
+
Benchmarker.scope() do
|
1583
|
+
task "foo" do nil end
|
1584
|
+
end
|
1585
|
+
end
|
1586
|
+
ok {sout} !~ /\e\[0;36m.*?\e\[0m/
|
1587
|
+
end
|
1588
|
+
- spec("[!muica] option '-F' specifies filter.") do
|
1589
|
+
ok {Benchmarker::OPTIONS} == {}
|
1590
|
+
Benchmarker.parse_cmdopts(['-F', 'task=ba*'])
|
1591
|
+
ok {Benchmarker::OPTIONS} == {filter: 'task=ba*'}
|
1592
|
+
called = []
|
1593
|
+
sout, serr = capture_sio do
|
1594
|
+
Benchmarker.scope(width: 20) do
|
1595
|
+
task "foo" do called << "foo" end
|
1596
|
+
task "bar", tag: 'curr' do called << "bar" end
|
1597
|
+
task "baz" do called << "baz" end
|
1598
|
+
end
|
1599
|
+
end
|
1600
|
+
ok {called} == ["bar", "baz"]
|
1601
|
+
#
|
1602
|
+
Benchmarker.parse_cmdopts(['-F', 'tag!=curr'])
|
1603
|
+
called = []
|
1604
|
+
sout, serr = capture_sio do
|
1605
|
+
Benchmarker.scope(width: 20) do
|
1606
|
+
task "foo" do called << "foo" end
|
1607
|
+
task "bar", tag: 'curr' do called << "bar" end
|
1608
|
+
task "baz" do called << "baz" end
|
1609
|
+
end
|
1610
|
+
end
|
1611
|
+
ok {called} == ["foo", "baz"]
|
1612
|
+
end
|
1613
|
+
- spec("[!3khc4] sets global variables if long option specified.") do
|
1614
|
+
ok {Benchmarker::OPTIONS} == {}
|
1615
|
+
ok {$opt_blabla} == nil
|
1616
|
+
Benchmarker.parse_cmdopts(['--blabla=123'])
|
1617
|
+
ok {Benchmarker::OPTIONS} == {}
|
1618
|
+
ok {$opt_blabla} == "123"
|
1619
|
+
Benchmarker.parse_cmdopts(['--blabla'])
|
1620
|
+
ok {Benchmarker::OPTIONS} == {}
|
1621
|
+
ok {$opt_blabla} == true
|
1622
|
+
end
|
634
1623
|
end
|
635
|
-
#spec "takes :real, :barchar, and :loop options." do
|
636
|
-
#end
|
637
1624
|
end
|
638
1625
|
|
639
|
-
def test_ranking
|
640
|
-
expected1 = <<'END'
|
641
1626
|
|
642
|
-
|
643
|
-
Yuki 10.5000 (100.0%) ********************
|
644
|
-
Haruhi 11.5000 ( 91.3%) ******************
|
645
|
-
Itsuki 12.5000 ( 84.0%) *****************
|
646
|
-
Kyon 13.5000 ( 77.8%) ****************
|
647
|
-
Mikuru 14.5000 ( 72.4%) **************
|
648
|
-
END
|
649
|
-
expected2 = <<'END'
|
1627
|
+
+ topic(Benchmark) do
|
650
1628
|
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
@r = Benchmarker::Reporter.new(:out=>@out)
|
666
|
-
@stats = Benchmarker::Stats.new(@r, :numerator=>1000*1000)
|
667
|
-
@stats.ranking(@tasks)
|
668
|
-
ok {@out} == expected2
|
1629
|
+
+ topic('.bm()') do
|
1630
|
+
- spec("[!2nf07] defines and runs benchmark.") do
|
1631
|
+
called = {foo: 0, bar: 0}
|
1632
|
+
sout, serr = capture_sio do
|
1633
|
+
Benchmark.bm do |x|
|
1634
|
+
x.report("foo") do called[:foo] += 1 end
|
1635
|
+
x.report("bar") do called[:bar] += 1 end
|
1636
|
+
end
|
1637
|
+
end
|
1638
|
+
ok {called} == {foo: 1, bar: 1}
|
1639
|
+
n = 0
|
1640
|
+
sout.scan(/^## +.*\nfoo +.*\nbar +.*/) { n+= 1 }
|
1641
|
+
ok {n} == 1
|
1642
|
+
ok {serr} == ""
|
669
1643
|
end
|
670
1644
|
end
|
671
|
-
end
|
672
|
-
|
673
|
-
def test_ratio_matrix
|
674
|
-
expected = <<'END'
|
675
1645
|
|
676
|
-
|
677
|
-
[
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
[
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
1646
|
+
+ topic('.bm()') do
|
1647
|
+
- spec("[!ezbb8] defines and runs benchmark twice, reports only 2nd result.") do
|
1648
|
+
called = {foo: 0, bar: 0}
|
1649
|
+
sout, serr = capture_sio do
|
1650
|
+
Benchmark.bmbm do |x|
|
1651
|
+
x.report("foo") do called[:foo] += 1 end
|
1652
|
+
x.report("bar") do called[:bar] += 1 end
|
1653
|
+
end
|
1654
|
+
end
|
1655
|
+
ok {called} == {foo: 2, bar: 2}
|
1656
|
+
n = 0
|
1657
|
+
sout.scan(/^## +.*\nfoo +.*\nbar +.*/) { n+= 1 }
|
1658
|
+
ok {n} == 1
|
1659
|
+
ok {serr} == ""
|
1660
|
+
end
|
686
1661
|
end
|
687
|
-
end
|
688
1662
|
|
689
|
-
end
|
1663
|
+
end
|
690
1664
|
|
691
1665
|
|
692
|
-
if __FILE__ == $0
|
693
|
-
Oktest::run_all()
|
694
1666
|
end
|