rgot 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +94 -5
- data/bin/rgot +18 -2
- data/lib/rgot.rb +6 -0
- data/lib/rgot/b.rb +41 -24
- data/lib/rgot/benchmark_result.rb +15 -0
- data/lib/rgot/m.rb +38 -6
- data/lib/rgot/pb.rb +15 -0
- data/lib/rgot/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b55640e6b13205e65a7e08765579b3566f43b385
|
4
|
+
data.tar.gz: 2b9727ef0256af4d11d272f2c4aa255ecf91053c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce0a920a44014f5b876382e6091018a1b447d9acd96e460e9077640e07047907221cc4b9946f849b09efcc0cbf65b881b78e8d88b100cf197ac2ebf53eb865c7
|
7
|
+
data.tar.gz: 516c281575d0fa554698adb4cd2e69af664670dba015922c31c7f9dcf67f874715adbd190cf3482e2bd9a08d99a10a50d6e44dcd728cf875ca783516e6bbbfea
|
data/README.md
CHANGED
@@ -83,6 +83,12 @@ module FooTest
|
|
83
83
|
end
|
84
84
|
```
|
85
85
|
|
86
|
+
```
|
87
|
+
$ rgot foo_test.rb --bench .
|
88
|
+
benchmark_something 14400000 81.392 ns/op
|
89
|
+
ok FooTest 2.782s
|
90
|
+
```
|
91
|
+
|
86
92
|
`b.n` is automatically adjusted.
|
87
93
|
|
88
94
|
## Example
|
@@ -141,14 +147,17 @@ But all file should be have one module (like golang package name).
|
|
141
147
|
|
142
148
|
```ruby
|
143
149
|
module XxxTest
|
150
|
+
# ...
|
144
151
|
end
|
145
152
|
```
|
146
153
|
|
147
154
|
## Method name
|
148
155
|
|
149
|
-
Method name should be set
|
156
|
+
Method name should be set `test_*` for testing.
|
150
157
|
|
151
|
-
And benchmark method should be set
|
158
|
+
And benchmark method should be set `benchmark_*`.
|
159
|
+
|
160
|
+
And example method should be set `example_*`.
|
152
161
|
|
153
162
|
```ruby
|
154
163
|
module XxxTest
|
@@ -157,10 +166,13 @@ module XxxTest
|
|
157
166
|
|
158
167
|
def benchmark_any_name(b)
|
159
168
|
end
|
169
|
+
|
170
|
+
def example_any_name
|
171
|
+
end
|
160
172
|
end
|
161
173
|
```
|
162
174
|
|
163
|
-
# Command
|
175
|
+
# Command line interface
|
164
176
|
|
165
177
|
```
|
166
178
|
$ rgot -h
|
@@ -169,6 +181,8 @@ Usage: rgot [options]
|
|
169
181
|
--bench [regexp] benchmark
|
170
182
|
--benchtime [sec] benchmark running time
|
171
183
|
--timeout [sec] set timeout sec to testing
|
184
|
+
--cpu [count,...] set cpu counts of comma splited
|
185
|
+
--thread [count,...] set thread counts of comma splited
|
172
186
|
--require [path] load some code before running
|
173
187
|
--load-path [path] Specify $LOAD_PATH directory
|
174
188
|
```
|
@@ -217,6 +231,41 @@ Run testing with benchmark.
|
|
217
231
|
|
218
232
|
Set `someone` if you only run benchmark to match `someone` method.(e.g. benchmark_someone_1)
|
219
233
|
|
234
|
+
### Parallel benchmark
|
235
|
+
|
236
|
+
Benchmark for parallel performance.
|
237
|
+
|
238
|
+
`--cpu` option set process counts (default 1).
|
239
|
+
|
240
|
+
And `--thread` option set thread counts (default 1).
|
241
|
+
|
242
|
+
Benchmark fork, run and report each by process counts.
|
243
|
+
|
244
|
+
(**process** and **thread** means ruby/linux process)
|
245
|
+
|
246
|
+
```ruby
|
247
|
+
module FooTest
|
248
|
+
def benchmark_any_func(b)
|
249
|
+
b.run_parallel do |pb|
|
250
|
+
# pb is instance of Rgot::PB
|
251
|
+
# call some time by b.n
|
252
|
+
while pb.next
|
253
|
+
some_func()
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
```
|
259
|
+
|
260
|
+
```
|
261
|
+
$ rgot foo_test.rb --bench . --cpu=2,4 --thread=2,4
|
262
|
+
benchmark_any_func-2(2) 40 13363604.899 ns/op
|
263
|
+
benchmark_any_func-2(4) 160 7125845.113 ns/op
|
264
|
+
benchmark_any_func-4(2) 160 7224815.534 ns/op
|
265
|
+
benchmark_any_func-4(4) 320 3652431.962 ns/op
|
266
|
+
ok FooTest 3.061s
|
267
|
+
```
|
268
|
+
|
220
269
|
## Timeout
|
221
270
|
|
222
271
|
```
|
@@ -322,10 +371,10 @@ Automatic number calculated by running time.
|
|
322
371
|
Recommend to this idiom.
|
323
372
|
|
324
373
|
```ruby
|
325
|
-
def
|
374
|
+
def benchmark_something(b)
|
326
375
|
i = 0
|
327
376
|
while i < b.n
|
328
|
-
|
377
|
+
something()
|
329
378
|
i += 1
|
330
379
|
end
|
331
380
|
end
|
@@ -335,6 +384,18 @@ end
|
|
335
384
|
|
336
385
|
Reset benchmark timer
|
337
386
|
|
387
|
+
```ruby
|
388
|
+
def benchmark_something(b)
|
389
|
+
obj = heavy_prepare_method()
|
390
|
+
b.reset_timer # you can ignore time of havy_prepare_method()
|
391
|
+
i = 0
|
392
|
+
while i < b.n
|
393
|
+
obj.something()
|
394
|
+
i += 1
|
395
|
+
end
|
396
|
+
end
|
397
|
+
```
|
398
|
+
|
338
399
|
## Rgot::B#start_timer
|
339
400
|
|
340
401
|
Start benchmark timer
|
@@ -342,3 +403,31 @@ Start benchmark timer
|
|
342
403
|
## Rgot::B#stop_timer
|
343
404
|
|
344
405
|
Stop benchmark timer
|
406
|
+
|
407
|
+
## Rgot::B#run_parallel
|
408
|
+
|
409
|
+
Start parallel benchmark using `fork` and `Thread.new`.
|
410
|
+
|
411
|
+
This method should be call with block.
|
412
|
+
|
413
|
+
The block argument is instance of Rgot::PB.
|
414
|
+
|
415
|
+
# Rgot::PB (Parallel Benchmark)
|
416
|
+
|
417
|
+
## Rgot::PB#next
|
418
|
+
|
419
|
+
Should be call this when parallel benchmark.
|
420
|
+
|
421
|
+
Repeat while return false.
|
422
|
+
|
423
|
+
Recommend this idiom.
|
424
|
+
|
425
|
+
```ruby
|
426
|
+
def benchmark_foo(b)
|
427
|
+
b.run_parallel do |pb|
|
428
|
+
while pb.next
|
429
|
+
some_func()
|
430
|
+
end
|
431
|
+
end
|
432
|
+
end
|
433
|
+
```
|
data/bin/rgot
CHANGED
@@ -21,6 +21,12 @@ parser = OptionParser.new do |o|
|
|
21
21
|
o.on '--timeout [sec]', "set timeout sec to testing" do |arg|
|
22
22
|
opts[:timeout] = arg
|
23
23
|
end
|
24
|
+
o.on '--cpu [count,...]', "set cpu counts of comma splited" do |arg|
|
25
|
+
opts[:cpu] = arg
|
26
|
+
end
|
27
|
+
o.on '--thread [count,...]', "set thread counts of comma splited" do |arg|
|
28
|
+
opts[:thread] = arg
|
29
|
+
end
|
24
30
|
o.on '--require [path]', "load some code before running" do |arg|
|
25
31
|
opts[:require_paths] << arg
|
26
32
|
end
|
@@ -91,9 +97,19 @@ modules.each do |test_module|
|
|
91
97
|
at_exit {
|
92
98
|
template = "%s\t%s\t%.3fs"
|
93
99
|
|
94
|
-
|
95
|
-
|
100
|
+
case $!
|
101
|
+
when SystemExit
|
102
|
+
if $!.success?
|
103
|
+
# exit 0
|
104
|
+
puts sprintf(template, "ok", test_module, Rgot.now - duration)
|
105
|
+
else
|
106
|
+
# exit 1
|
107
|
+
puts sprintf(template, "FAIL", test_module, Rgot.now - duration)
|
108
|
+
end
|
109
|
+
when NilClass
|
110
|
+
# not raise, not exit
|
96
111
|
else
|
112
|
+
# any exception
|
97
113
|
puts sprintf(template, "FAIL", test_module, Rgot.now - duration)
|
98
114
|
end
|
99
115
|
}
|
data/lib/rgot.rb
CHANGED
@@ -4,6 +4,8 @@ module Rgot
|
|
4
4
|
require 'rgot/m'
|
5
5
|
require 'rgot/t'
|
6
6
|
require 'rgot/b'
|
7
|
+
require 'rgot/pb'
|
8
|
+
require 'rgot/benchmark_result'
|
7
9
|
require 'rgot/example_parser'
|
8
10
|
|
9
11
|
class OptionError < StandardError
|
@@ -31,5 +33,9 @@ module Rgot
|
|
31
33
|
Time.now
|
32
34
|
end
|
33
35
|
end
|
36
|
+
|
37
|
+
def benchmark(opts={}, &block)
|
38
|
+
B.new(nil, nil, opts).run(&block)
|
39
|
+
end
|
34
40
|
end
|
35
41
|
end
|
data/lib/rgot/b.rb
CHANGED
@@ -1,16 +1,15 @@
|
|
1
1
|
module Rgot
|
2
2
|
class B < Common
|
3
3
|
attr_accessor :n
|
4
|
-
def initialize(benchmark_module, name, opts)
|
4
|
+
def initialize(benchmark_module, name, opts={})
|
5
5
|
super()
|
6
6
|
@n = 1
|
7
7
|
@module = benchmark_module
|
8
8
|
@name = name
|
9
9
|
@opts = opts
|
10
|
-
@benchtime = @opts.fetch(:benchtime, 1).to_f
|
11
10
|
@timer_on = false
|
12
11
|
@duration = 0
|
13
|
-
@module.extend @module
|
12
|
+
@module.extend @module if @module
|
14
13
|
end
|
15
14
|
|
16
15
|
def start_timer
|
@@ -34,43 +33,61 @@ module Rgot
|
|
34
33
|
@duration = 0
|
35
34
|
end
|
36
35
|
|
37
|
-
def run
|
36
|
+
def run(&block)
|
38
37
|
n = 1
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
38
|
+
benchtime = @opts.fetch(:benchtime, 1).to_f
|
39
|
+
run_n(n.to_i, block)
|
40
|
+
while !failed? && @duration < benchtime && @n < 1e9
|
41
|
+
if @duration < (benchtime / 100.0)
|
42
|
+
@n *= 100
|
43
|
+
elsif @duration < (benchtime / 10.0)
|
44
|
+
@n *= 10
|
45
|
+
elsif @duration < (benchtime / 5.0)
|
46
|
+
@n *= 5
|
47
|
+
elsif @duration < (benchtime / 2.0)
|
48
|
+
@n *= 2
|
49
49
|
else
|
50
|
-
n
|
50
|
+
if @n.to_i == 1
|
51
|
+
break
|
52
|
+
end
|
53
|
+
@n *= 1.2
|
51
54
|
end
|
52
|
-
run_n(n)
|
55
|
+
run_n(@n.to_i, block)
|
53
56
|
end
|
57
|
+
|
58
|
+
BenchmarkResult.new(n: @n, t: @duration)
|
54
59
|
end
|
55
60
|
|
56
|
-
def
|
57
|
-
|
61
|
+
def run_parallel
|
62
|
+
raise LocalJumpError, "no block given" unless block_given?
|
63
|
+
|
64
|
+
@opts[:procs].times do
|
65
|
+
fork {
|
66
|
+
Array.new(@opts[:threads]) {
|
67
|
+
Thread.new {
|
68
|
+
yield PB.new(bn: @n)
|
69
|
+
}.tap { |t| t.abort_on_exception = true }
|
70
|
+
}.each(&:join)
|
71
|
+
}
|
72
|
+
end
|
73
|
+
@n *= @opts[:procs] * @opts[:threads]
|
74
|
+
Process.waitall
|
58
75
|
end
|
59
76
|
|
60
77
|
private
|
61
78
|
|
62
|
-
def run_n(n)
|
79
|
+
def run_n(n, block=nil)
|
63
80
|
GC.start
|
64
81
|
i = 0
|
65
82
|
@n = n
|
66
83
|
reset_timer
|
67
84
|
start_timer
|
68
|
-
|
85
|
+
if block
|
86
|
+
block.call(self)
|
87
|
+
else
|
88
|
+
@module.instance_method(@name).bind(@module).call(self)
|
89
|
+
end
|
69
90
|
stop_timer
|
70
91
|
end
|
71
|
-
|
72
|
-
def call
|
73
|
-
@module.instance_method(@name).bind(@module).call(self)
|
74
|
-
end
|
75
92
|
end
|
76
93
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Rgot
|
2
|
+
class BenchmarkResult
|
3
|
+
# Ruby-2.0.0 wants default value of keyword_argument
|
4
|
+
def initialize(n: nil, t: nil)
|
5
|
+
raise ArgumentError, "missing keyword: n" unless n
|
6
|
+
raise ArgumentError, "missing keyword: t" unless t
|
7
|
+
@n = n
|
8
|
+
@t = t
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
sprintf("%d\t%.3f ns/op", @n, @t / @n * 1_000_000_000)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/rgot/m.rb
CHANGED
@@ -3,11 +3,29 @@ require 'stringio'
|
|
3
3
|
module Rgot
|
4
4
|
class M
|
5
5
|
# Ruby-2.0.0 wants default value of keyword_argument
|
6
|
-
def initialize(tests:
|
6
|
+
def initialize(tests: nil, benchmarks: nil, examples: nil, opts: {})
|
7
|
+
raise ArgumentError, "missing keyword: tests" unless tests
|
8
|
+
raise ArgumentError, "missing keyword: benchmarks" unless benchmarks
|
9
|
+
raise ArgumentError, "missing keyword: examples" unless examples
|
10
|
+
|
7
11
|
@tests = tests
|
8
12
|
@benchmarks = benchmarks
|
9
13
|
@examples = examples
|
10
14
|
@opts = opts
|
15
|
+
@cpu_list = @opts.fetch(:cpu, "1").split(',').map { |i|
|
16
|
+
j = i.to_i
|
17
|
+
if j == 0
|
18
|
+
raise OptionError, "expect integer string, got #{i.inspect}"
|
19
|
+
end
|
20
|
+
j
|
21
|
+
}
|
22
|
+
@thread_list = @opts.fetch(:thread, "1").split(',').map { |i|
|
23
|
+
j = i.to_i
|
24
|
+
if j == 0
|
25
|
+
raise OptionError, "expect integer string, got #{i.inspect}"
|
26
|
+
end
|
27
|
+
j
|
28
|
+
}
|
11
29
|
end
|
12
30
|
|
13
31
|
def run
|
@@ -51,11 +69,23 @@ module Rgot
|
|
51
69
|
@benchmarks.each do |bench|
|
52
70
|
next unless /#{@opts[:bench]}/ =~ bench.name
|
53
71
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
72
|
+
@cpu_list.each do |procs|
|
73
|
+
@thread_list.each do |threads|
|
74
|
+
opts = @opts.dup
|
75
|
+
opts[:procs] = procs
|
76
|
+
opts[:threads] = threads
|
77
|
+
b = B.new(bench.module, bench.name.to_sym, opts)
|
78
|
+
|
79
|
+
benchname = bench.name.to_s
|
80
|
+
benchname << "-#{procs}" if 1 < procs
|
81
|
+
benchname << "(#{threads})" if 1 < threads
|
82
|
+
print "#{benchname}\t"
|
83
|
+
result = b.run
|
84
|
+
puts result
|
85
|
+
if b.failed?
|
86
|
+
ok = false
|
87
|
+
end
|
88
|
+
end
|
59
89
|
end
|
60
90
|
end
|
61
91
|
ok
|
@@ -88,6 +118,8 @@ module Rgot
|
|
88
118
|
end
|
89
119
|
|
90
120
|
def capture
|
121
|
+
raise LocalJumpError, "no block given" unless block_given?
|
122
|
+
|
91
123
|
orig_out, orig_err = $stdout, $stderr
|
92
124
|
out, err = StringIO.new, StringIO.new
|
93
125
|
$stdout, $stderr = out, err
|
data/lib/rgot/pb.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module Rgot
|
2
|
+
class PB
|
3
|
+
attr_accessor :bn
|
4
|
+
|
5
|
+
# Ruby-2.0.0 wants default value of keyword_argument
|
6
|
+
def initialize(bn: nil)
|
7
|
+
raise ArgumentError, "missing keyword: bn" unless bn
|
8
|
+
@bn = bn
|
9
|
+
end
|
10
|
+
|
11
|
+
def next
|
12
|
+
(0 < @bn).tap { @bn -= 1 }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/rgot/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rgot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ksss
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-08-
|
11
|
+
date: 2015-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -55,9 +55,11 @@ files:
|
|
55
55
|
- bin/rgot
|
56
56
|
- lib/rgot.rb
|
57
57
|
- lib/rgot/b.rb
|
58
|
+
- lib/rgot/benchmark_result.rb
|
58
59
|
- lib/rgot/common.rb
|
59
60
|
- lib/rgot/example_parser.rb
|
60
61
|
- lib/rgot/m.rb
|
62
|
+
- lib/rgot/pb.rb
|
61
63
|
- lib/rgot/t.rb
|
62
64
|
- lib/rgot/version.rb
|
63
65
|
- rgot.gemspec
|
@@ -81,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
83
|
version: '0'
|
82
84
|
requirements: []
|
83
85
|
rubyforge_project:
|
84
|
-
rubygems_version: 2.4.5
|
86
|
+
rubygems_version: 2.4.5.1
|
85
87
|
signing_key:
|
86
88
|
specification_version: 4
|
87
89
|
summary: Ruby + Golang Testing = Rgot
|