benchmark_driver 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitignore +0 -4
- data/.travis.yml +10 -6
- data/Gemfile +7 -2
- data/Gemfile.lock +30 -0
- data/README.md +125 -117
- data/Rakefile +14 -7
- data/benchmark_driver.gemspec +2 -4
- data/bin/console +1 -1
- data/examples/call.rb +12 -0
- data/examples/call_blank.rb +13 -0
- data/examples/call_erb.rb +33 -0
- data/examples/call_interpolation.rb +13 -0
- data/examples/exec_blank.rb +14 -0
- data/examples/exec_interpolation.rb +15 -0
- data/examples/yaml/array_duration_time.yml +3 -0
- data/examples/yaml/array_loop.yml +3 -0
- data/examples/yaml/array_loop_memory.yml +6 -0
- data/examples/yaml/array_loop_time.yml +4 -0
- data/examples/yaml/blank_hash.yml +8 -0
- data/examples/yaml/blank_hash_array.yml +10 -0
- data/examples/yaml/blank_loop.yml +9 -0
- data/examples/yaml/blank_loop_time.yml +10 -0
- data/examples/yaml/blank_string.yml +6 -0
- data/examples/yaml/blank_string_array.yml +8 -0
- data/examples/yaml/example_multi.yml +6 -0
- data/{benchmarks → examples/yaml}/example_single.yml +0 -0
- data/exe/benchmark-driver +44 -18
- data/lib/benchmark/driver.rb +52 -257
- data/lib/benchmark/driver/benchmark_result.rb +21 -0
- data/lib/benchmark/driver/configuration.rb +65 -0
- data/lib/benchmark/driver/duration_runner.rb +24 -0
- data/lib/benchmark/driver/error.rb +16 -0
- data/lib/benchmark/driver/repeatable_runner.rb +18 -0
- data/lib/benchmark/driver/ruby_dsl_parser.rb +57 -0
- data/lib/benchmark/driver/time.rb +12 -0
- data/lib/benchmark/driver/version.rb +2 -2
- data/lib/benchmark/driver/yaml_parser.rb +103 -0
- data/lib/benchmark/output.rb +16 -0
- data/lib/benchmark/output/ips.rb +114 -0
- data/lib/benchmark/output/memory.rb +57 -0
- data/lib/benchmark/output/time.rb +57 -0
- data/lib/benchmark/runner.rb +13 -0
- data/lib/benchmark/runner/call.rb +97 -0
- data/lib/benchmark/runner/exec.rb +190 -0
- metadata +40 -10
- data/benchmarks/core/array.yml +0 -4
- data/benchmarks/example_multi.yml +0 -10
- data/benchmarks/lib/erb.yml +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 771d93093383594ac93a9f3456b646f9ef484578
|
4
|
+
data.tar.gz: 41b2b41209e834a8983dad25843188325f8fb009
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 697ed2bab69c631bb9104adae293105b323b7ccb3321c123c85a18f44f5bb5a4e352fc06257b637233d8dbe73cb7ebc19aa63f93c8f53e8b9dbf10daa4c13bf9
|
7
|
+
data.tar.gz: ba4fd20c4dc8b506fa2971416446ba86594604c336b0a728aef071d385a3f46e7ea41f34e6061c0ace32bb61412d488fdfd7d2719b39cd2541b9ef8cb3f453c3
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,11 +1,15 @@
|
|
1
|
-
sudo: false
|
2
1
|
language: ruby
|
3
2
|
rvm:
|
3
|
+
- 2.1.10
|
4
|
+
- 2.2.8
|
5
|
+
- 2.3.5
|
4
6
|
- 2.4.2
|
7
|
+
- ruby-head
|
8
|
+
cache: bundler
|
9
|
+
branches:
|
10
|
+
only:
|
11
|
+
- master
|
5
12
|
before_install: gem install bundler -v 1.15.4
|
6
13
|
script:
|
7
|
-
- bundle exec rake
|
8
|
-
|
9
|
-
# Test some options
|
10
|
-
- bundle exec exe/benchmark-driver benchmarks/example_single.yml -e ruby1::ruby -e ruby2::ruby -i
|
11
|
-
- bundle exec exe/benchmark-driver benchmarks/example_single.yml -e ruby1::ruby -e ruby2::ruby -i 2
|
14
|
+
- bundle exec rake ruby_examples
|
15
|
+
- bundle exec rake yaml_examples
|
data/Gemfile
CHANGED
@@ -1,8 +1,13 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
git_source(:github) {
|
3
|
+
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
4
4
|
|
5
5
|
# Specify your gem's dependencies in benchmark_driver.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
+
# For my debugging
|
8
9
|
gem 'pry'
|
10
|
+
|
11
|
+
# For benchmark examples
|
12
|
+
gem 'erubi'
|
13
|
+
gem 'erubis'
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
benchmark_driver (0.4.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
coderay (1.1.2)
|
10
|
+
erubi (1.7.0)
|
11
|
+
erubis (2.7.0)
|
12
|
+
method_source (0.9.0)
|
13
|
+
pry (0.11.1)
|
14
|
+
coderay (~> 1.1.0)
|
15
|
+
method_source (~> 0.9.0)
|
16
|
+
rake (12.3.0)
|
17
|
+
|
18
|
+
PLATFORMS
|
19
|
+
ruby
|
20
|
+
|
21
|
+
DEPENDENCIES
|
22
|
+
benchmark_driver!
|
23
|
+
bundler
|
24
|
+
erubi
|
25
|
+
erubis
|
26
|
+
pry
|
27
|
+
rake
|
28
|
+
|
29
|
+
BUNDLED WITH
|
30
|
+
1.16.0
|
data/README.md
CHANGED
@@ -1,23 +1,104 @@
|
|
1
1
|
# Benchmark::Driver [](https://travis-ci.org/k0kubun/benchmark_driver)
|
2
2
|
|
3
|
-
|
3
|
+
Fully-featured accurate benchmark driver for Ruby
|
4
|
+
|
5
|
+
## Project Status
|
6
|
+
|
7
|
+
**Under Construction**
|
8
|
+
|
9
|
+
## Features
|
10
|
+
NOTE: Pending ones are ~slashed~.
|
11
|
+
|
12
|
+
### Accurate Measurement
|
13
|
+
|
14
|
+
- Low overhead benchmark by running generated script instead of calling Proc
|
15
|
+
- Running multiple times to minimize measurement errors
|
16
|
+
- Profiling memory, high-precision real time, ~user time and system time~
|
17
|
+
|
18
|
+
### Pluggable & Fully Featured
|
19
|
+
|
20
|
+
- Flexible and real-time output format in ips, execution time, ~markdown table~, etc.
|
21
|
+
- Runner and output are all pluggable
|
22
|
+
- ~Integrated benchmark support using external libraries~
|
23
|
+
|
24
|
+
### Flexible Interface
|
25
|
+
|
26
|
+
- Ruby interface similar to benchmark stdlib, benchmark-ips
|
27
|
+
- YAML input to easily manage structured benchmark set
|
28
|
+
- Comparing multiple Ruby binaries, even with miniruby
|
4
29
|
|
5
30
|
## Installation
|
6
31
|
|
7
|
-
|
32
|
+
```
|
33
|
+
$ gem install benchmark_driver
|
34
|
+
```
|
8
35
|
|
9
36
|
## Usage
|
10
37
|
|
38
|
+
### Ruby Interface: Compatible Mode
|
39
|
+
|
40
|
+
This interface is compatible with `Benchmark.bm` and `Benchmark.ips`, so it's good for migration.
|
41
|
+
|
42
|
+
```rb
|
43
|
+
require 'benchmark/driver'
|
44
|
+
require 'active_support/all'
|
45
|
+
array = []
|
46
|
+
|
47
|
+
Benchmark.driver do |x|
|
48
|
+
x.report('blank?') { array.blank? }
|
49
|
+
x.report('empty?') { array.empty? }
|
50
|
+
x.compare!
|
51
|
+
end
|
52
|
+
```
|
53
|
+
|
54
|
+
### Ruby Interface: Low Overhead Mode
|
55
|
+
|
56
|
+
This interface generates code to profile with low overhead and executes it.
|
57
|
+
|
58
|
+
```rb
|
59
|
+
require 'benchmark/driver'
|
60
|
+
|
61
|
+
Benchmark.driver do |x|
|
62
|
+
x.prelude = <<~RUBY
|
63
|
+
require 'active_support/all'
|
64
|
+
array = []
|
65
|
+
RUBY
|
66
|
+
|
67
|
+
x.report('blank?', script: 'array.blank?')
|
68
|
+
x.report('empty?', script: 'array.empty?')
|
69
|
+
end
|
70
|
+
```
|
71
|
+
|
72
|
+
or simply:
|
73
|
+
|
74
|
+
```rb
|
75
|
+
require 'benchmark/driver'
|
76
|
+
|
77
|
+
Benchmark.driver do |x|
|
78
|
+
x.prelude = <<~RUBY
|
79
|
+
require 'active_support/all'
|
80
|
+
array = []
|
81
|
+
RUBY
|
82
|
+
|
83
|
+
x.report(script: 'array.blank?')
|
84
|
+
x.report(script: 'array.empty?')
|
85
|
+
end
|
86
|
+
```
|
87
|
+
|
88
|
+
### Structured YAML Input
|
89
|
+
|
90
|
+
With `benchmark-driver` command, you can describe benchmark with YAML input.
|
91
|
+
|
11
92
|
```
|
12
93
|
$ benchmark-driver -h
|
13
94
|
Usage: benchmark-driver [options] [YAML]
|
14
95
|
-e, --executables [EXECS] Ruby executables (e1::path1; e2::path2; e3::path3;...)
|
15
|
-
|
16
|
-
-
|
17
|
-
-
|
96
|
+
--rbenv [VERSIONS] Ruby executables in rbenv (2.3.5;2.4.2;...)
|
97
|
+
-c, --compare Compare results (currently only supported in ips output)
|
98
|
+
-r, --repeat-count [NUM] Try benchmark NUM times and use the fastest result
|
18
99
|
```
|
19
100
|
|
20
|
-
|
101
|
+
#### Running single script
|
21
102
|
|
22
103
|
With following `example_single.yml`,
|
23
104
|
|
@@ -31,31 +112,19 @@ benchmark: erb.result
|
|
31
112
|
you can benchmark the script with multiple ruby executables.
|
32
113
|
|
33
114
|
```
|
34
|
-
$ benchmark-driver
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
Speedup ratio: compare with the result of `ruby1' (greater is better)
|
41
|
-
name ruby2
|
42
|
-
example_single 0.986
|
43
|
-
```
|
44
|
-
|
45
|
-
And you can change benchmark output to IPS (iteration per second) by `-i` option.
|
115
|
+
$ exe/benchmark-driver examples/yaml/example_single.yml --rbenv '2.4.2;trunk' --compare
|
116
|
+
Warming up --------------------------------------
|
117
|
+
erb.result 10.973k i/100ms
|
118
|
+
Calculating -------------------------------------
|
119
|
+
2.4.2 trunk
|
120
|
+
erb.result 109.268k 123.611k i/s - 548.675k in 4.017080s 4.438720s
|
46
121
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
ruby1 ruby2
|
51
|
-
example_single 99414.1 i/s 99723.3 i/s
|
52
|
-
|
53
|
-
Comparison: example_single
|
54
|
-
ruby2: 99723.3 i/s
|
55
|
-
ruby1: 99414.1 i/s - 1.00x slower
|
122
|
+
Comparison:
|
123
|
+
erb.result (trunk): 123611.1 i/s
|
124
|
+
erb.result (2.4.2): 109268.4 i/s - 1.13x slower
|
56
125
|
```
|
57
126
|
|
58
|
-
|
127
|
+
#### Running multiple scripts
|
59
128
|
|
60
129
|
One YAML file can contain multiple benchmark scripts.
|
61
130
|
With following `example_multi.yml`,
|
@@ -64,103 +133,42 @@ With following `example_multi.yml`,
|
|
64
133
|
prelude: |
|
65
134
|
a = 'a' * 100
|
66
135
|
b = 'b' * 100
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
[a, b].join
|
71
|
-
- name: interpolation
|
72
|
-
benchmark: |
|
73
|
-
"#{a}#{b}"
|
136
|
+
benchmark:
|
137
|
+
join: '[a, b].join'
|
138
|
+
str-interp: '"#{a}#{b}"'
|
74
139
|
```
|
75
140
|
|
76
141
|
you can benchmark the scripts with multiple ruby executables.
|
77
142
|
|
78
143
|
```
|
79
|
-
$ benchmark-driver
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
name ruby2
|
88
|
-
join 1.045
|
89
|
-
interpolation 1.002
|
90
|
-
```
|
144
|
+
$ exe/benchmark-driver examples/yaml/example_multi.yml --rbenv '2.4.2;trunk' --compare
|
145
|
+
Warming up --------------------------------------
|
146
|
+
join 515.787k i/100ms
|
147
|
+
str-interp 438.646k i/100ms
|
148
|
+
Calculating -------------------------------------
|
149
|
+
2.4.2 trunk
|
150
|
+
join 5.200M 4.740M i/s - 20.631M in 3.967750s 4.352565s
|
151
|
+
str-interp 4.306M 6.034M i/s - 21.932M in 4.075159s 3.634986s
|
91
152
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
interpolation 4263170.0 i/s 4044083.0 i/s
|
98
|
-
|
99
|
-
Comparison: join
|
100
|
-
ruby1: 4701954.3 i/s
|
101
|
-
ruby2: 4639520.3 i/s - 1.01x slower
|
102
|
-
|
103
|
-
Comparison: interpolation
|
104
|
-
ruby1: 4263170.0 i/s
|
105
|
-
ruby2: 4044083.0 i/s - 1.05x slower
|
106
|
-
```
|
107
|
-
|
108
|
-
### Configuring modes
|
109
|
-
|
110
|
-
There are 2 modes:
|
111
|
-
|
112
|
-
- Loop count: Enabled by `-l`. Optionally you can change count to loop by `-l COUNT`.
|
113
|
-
- IPS: Enabled by `-i`. Optionally you can change duration by `-i DURATION`.
|
114
|
-
|
115
|
-
Specifying both `-l` and `-i` is nonsense.
|
116
|
-
|
117
|
-
### YAML syntax
|
118
|
-
You can specify `benchmark:` or `benchmarks:`.
|
119
|
-
|
120
|
-
#### Single
|
121
|
-
```yml
|
122
|
-
name: String # optional (default: file name)
|
123
|
-
prelude: String # optional
|
124
|
-
loop_count: Integer # optional
|
125
|
-
benchmark: String # required
|
126
|
-
```
|
127
|
-
|
128
|
-
#### Multi
|
129
|
-
|
130
|
-
```yml
|
131
|
-
prelude: String # optional (shared)
|
132
|
-
loop_count: Integer # optional (shared)
|
133
|
-
benchmarks:
|
134
|
-
- name: String # required
|
135
|
-
prelude: String # optional (benchmark specific)
|
136
|
-
loop_count: Integer # optional (benchmark specific)
|
137
|
-
benchmark: String # required
|
138
|
-
```
|
139
|
-
|
140
|
-
### Debugging
|
141
|
-
|
142
|
-
If you have a trouble like an unexpectedly fast result, you should check benchmark script by `-v`.
|
143
|
-
|
144
|
-
```
|
145
|
-
$ benchmark-driver benchmarks/example_multi.yml -v
|
146
|
-
--- Running "join" with "ruby" 957780 times ---
|
147
|
-
a = 'a' * 100
|
148
|
-
b = 'b' * 100
|
149
|
-
|
150
|
-
|
151
|
-
i = 0
|
152
|
-
while i < 957780
|
153
|
-
i += 1
|
154
|
-
[a, b].join
|
155
|
-
|
156
|
-
end
|
153
|
+
Comparison:
|
154
|
+
str-interp (trunk): 6033674.6 i/s
|
155
|
+
join (2.4.2): 5199794.6 i/s - 1.16x slower
|
156
|
+
join (trunk): 4740075.1 i/s - 1.27x slower
|
157
|
+
str-interp (2.4.2): 4305563.1 i/s - 1.40x slower
|
157
158
|
```
|
158
159
|
|
159
160
|
## TODO
|
160
|
-
|
161
|
-
-
|
162
|
-
-
|
163
|
-
-
|
161
|
+
### Runner
|
162
|
+
- [x] Call
|
163
|
+
- [x] Exec
|
164
|
+
- [ ] Eval
|
165
|
+
|
166
|
+
### Output
|
167
|
+
- [x] IPS
|
168
|
+
- [x] Time
|
169
|
+
- [ ] CPU/System/Real Time
|
170
|
+
- [ ] Memory
|
171
|
+
- [ ] Markdown Table
|
164
172
|
|
165
173
|
## Contributing
|
166
174
|
|
@@ -168,4 +176,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/k0kubu
|
|
168
176
|
|
169
177
|
## License
|
170
178
|
|
171
|
-
The gem is available as open source under the terms of the [MIT License](
|
179
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
CHANGED
@@ -1,15 +1,22 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
|
+
require 'shellwords'
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
task :ruby_examples do
|
5
|
+
Dir.glob(File.expand_path('./examples/*.rb', __dir__)).sort.each do |file|
|
6
|
+
Bundler.with_clean_env do
|
7
|
+
sh ['time', 'bundle', 'exec', 'ruby', file].shelljoin
|
8
|
+
end
|
9
|
+
puts
|
10
|
+
end
|
11
|
+
end
|
7
12
|
|
8
|
-
|
13
|
+
task :yaml_examples do
|
14
|
+
Dir.glob(File.expand_path('./examples/yaml/*.yml', __dir__)).sort.each do |file|
|
9
15
|
Bundler.with_clean_env do
|
10
|
-
sh [
|
16
|
+
sh ['time', 'bundle', 'exec', 'exe/benchmark-driver', file].shelljoin
|
11
17
|
end
|
18
|
+
puts
|
12
19
|
end
|
13
20
|
end
|
14
21
|
|
15
|
-
task default: :
|
22
|
+
task default: [:ruby_examples, :yaml_examples]
|
data/benchmark_driver.gemspec
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# coding: utf-8
|
2
1
|
lib = File.expand_path('../lib', __FILE__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
require 'benchmark/driver/version'
|
@@ -9,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
9
8
|
spec.authors = ['Takashi Kokubun']
|
10
9
|
spec.email = ['takashikkbn@gmail.com']
|
11
10
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
11
|
+
spec.summary = 'Fully-featured accurate benchmark driver for Ruby'
|
12
|
+
spec.description = 'Fully-featured accurate benchmark driver for Ruby'
|
14
13
|
spec.homepage = 'https://github.com/k0kubun/benchmark_driver'
|
15
14
|
spec.license = 'MIT'
|
16
15
|
|
@@ -20,7 +19,6 @@ Gem::Specification.new do |spec|
|
|
20
19
|
spec.bindir = 'exe'
|
21
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
21
|
spec.require_paths = ['lib']
|
23
|
-
spec.required_ruby_version = '>= 2.3.0'
|
24
22
|
|
25
23
|
spec.add_development_dependency 'bundler'
|
26
24
|
spec.add_development_dependency 'rake'
|
data/bin/console
CHANGED