benchmark_driver 0.8.6 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +1 -3
- data/CHANGELOG.md +9 -0
- data/Gemfile +1 -6
- data/README.md +51 -52
- data/benchmark_driver.gemspec +3 -2
- data/bin/console +4 -11
- data/examples/exec_blank.rb +2 -2
- data/examples/exec_blank_simple.rb +2 -3
- data/exe/benchmark-driver +74 -83
- data/lib/benchmark_driver.rb +12 -1
- data/lib/benchmark_driver/config.rb +36 -0
- data/lib/benchmark_driver/default_job.rb +12 -0
- data/lib/benchmark_driver/default_job_parser.rb +68 -0
- data/lib/benchmark_driver/job_parser.rb +42 -0
- data/lib/benchmark_driver/metrics.rb +17 -0
- data/lib/benchmark_driver/output.rb +27 -0
- data/lib/benchmark_driver/output/compare.rb +196 -0
- data/lib/benchmark_driver/output/markdown.rb +102 -0
- data/lib/benchmark_driver/output/simple.rb +97 -0
- data/lib/benchmark_driver/rbenv.rb +11 -0
- data/lib/benchmark_driver/ruby_interface.rb +51 -0
- data/lib/benchmark_driver/runner.rb +42 -0
- data/lib/benchmark_driver/runner/ips.rb +239 -0
- data/lib/benchmark_driver/runner/memory.rb +142 -0
- data/lib/benchmark_driver/runner/time.rb +18 -0
- data/lib/benchmark_driver/struct.rb +85 -0
- data/lib/benchmark_driver/version.rb +3 -0
- metadata +21 -33
- data/bin/bench +0 -4
- data/examples/call.rb +0 -12
- data/examples/call_blank.rb +0 -13
- data/examples/call_erb.rb +0 -33
- data/examples/call_interpolation.rb +0 -13
- data/examples/eval_blank.rb +0 -12
- data/examples/eval_blank_loop.rb +0 -13
- data/examples/eval_interpolation.rb +0 -15
- data/lib/benchmark/driver.rb +0 -101
- data/lib/benchmark/driver/benchmark_result.rb +0 -21
- data/lib/benchmark/driver/bundle_installer.rb +0 -45
- data/lib/benchmark/driver/bundler.rb +0 -12
- data/lib/benchmark/driver/configuration.rb +0 -77
- data/lib/benchmark/driver/duration_runner.rb +0 -24
- data/lib/benchmark/driver/error.rb +0 -16
- data/lib/benchmark/driver/repeatable_runner.rb +0 -18
- data/lib/benchmark/driver/ruby_dsl_parser.rb +0 -78
- data/lib/benchmark/driver/time.rb +0 -12
- data/lib/benchmark/driver/version.rb +0 -5
- data/lib/benchmark/driver/yaml_parser.rb +0 -55
- data/lib/benchmark/output.rb +0 -20
- data/lib/benchmark/output/ips.rb +0 -143
- data/lib/benchmark/output/markdown.rb +0 -73
- data/lib/benchmark/output/memory.rb +0 -57
- data/lib/benchmark/output/time.rb +0 -57
- data/lib/benchmark/runner.rb +0 -14
- data/lib/benchmark/runner/call.rb +0 -97
- data/lib/benchmark/runner/eval.rb +0 -147
- data/lib/benchmark/runner/exec.rb +0 -193
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0cd5a98489bf28a8f6439e66e91350b20d330433
|
4
|
+
data.tar.gz: bd97724eb0f7bb197bd2453b8eccb17e8fa5dcf2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9debc903a940716911021dafe54dadd4be762259bb8c170c13266b6c15bd56f1762368d4a8982e75d326870b9611be65ba9fe30081a71c91874c489a516aa115
|
7
|
+
data.tar.gz: 72dbf0e5038f7218311364bf5226c4b909a40bb4ab343ccb393a2e76a14c8fe8db4d4f986203fcf6d16a0147afcdd1cf0b8456c19be511b31e49dfbb1b699112
|
data/.travis.yml
CHANGED
@@ -5,13 +5,11 @@ rvm:
|
|
5
5
|
- 2.3.6
|
6
6
|
- 2.4.3
|
7
7
|
- 2.5.0
|
8
|
-
- ruby-head
|
9
8
|
cache: bundler
|
10
9
|
branches:
|
11
10
|
only:
|
12
11
|
- master
|
13
|
-
before_install:
|
14
|
-
- gem update --system
|
12
|
+
before_install: gem install bundler -v 1.15.4
|
15
13
|
script:
|
16
14
|
- bundle exec rake ruby_examples
|
17
15
|
- bundle exec rake yaml_examples
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
# v0.9.0
|
2
|
+
|
3
|
+
- The concept of runner is renewed
|
4
|
+
- Now it's for specifying metrics like ips, time, memory usage
|
5
|
+
- Old runners (:call and :eval) are no longer supported. :exec only.
|
6
|
+
- So Ruby interface can't take Proc
|
7
|
+
- YAML can have arbitrary format depending on the runner
|
8
|
+
- `--compare` option is dropped and changed to `--output compare`
|
9
|
+
|
1
10
|
# v0.8.6
|
2
11
|
|
3
12
|
- Automatically require `benchmark/output/foo` when `-o foo` is specified
|
data/Gemfile
CHANGED
@@ -2,12 +2,7 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
4
4
|
|
5
|
-
# Specify your gem's dependencies in
|
5
|
+
# Specify your gem's dependencies in benchmark-driver.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
-
# For my debugging
|
9
8
|
gem 'pry'
|
10
|
-
|
11
|
-
# For benchmark examples
|
12
|
-
gem 'erubi'
|
13
|
-
gem 'erubis'
|
data/README.md
CHANGED
@@ -1,23 +1,24 @@
|
|
1
|
-
#
|
1
|
+
# BenchmarkDriver [![Build Status](https://travis-ci.org/k0kubun/benchmark_driver.svg?branch=master)](https://travis-ci.org/k0kubun/benchmark_driver)
|
2
2
|
|
3
3
|
Fully-featured accurate benchmark driver for Ruby
|
4
4
|
|
5
5
|
## Project Status
|
6
6
|
|
7
|
-
|
7
|
+
**Under Construction**
|
8
8
|
|
9
9
|
## Features
|
10
10
|
### Accurate Measurement
|
11
11
|
|
12
12
|
- Low overhead benchmark by running generated script instead of calling Proc
|
13
|
+
- Profiling memory, high-precision real time, user time and system time
|
13
14
|
- Running multiple times to minimize measurement errors
|
14
|
-
- Profiling memory, high-precision real time
|
15
15
|
|
16
16
|
### Pluggable & Fully Featured
|
17
17
|
|
18
18
|
- Flexible and real-time output format in ips, execution time, markdown table, etc.
|
19
|
-
-
|
20
|
-
-
|
19
|
+
- Benchmark with various profiling/running options
|
20
|
+
- Integrated benchmark support using external libraries
|
21
|
+
- Runner, profiler and output format are all pluggable
|
21
22
|
|
22
23
|
### Flexible Interface
|
23
24
|
|
@@ -33,32 +34,19 @@ $ gem install benchmark_driver
|
|
33
34
|
|
34
35
|
## Usage
|
35
36
|
|
36
|
-
### Ruby Interface
|
37
|
-
|
38
|
-
This interface is compatible with `Benchmark.bm` and `Benchmark.ips`, so it's good for migration.
|
39
|
-
|
40
|
-
```rb
|
41
|
-
require 'benchmark/driver'
|
42
|
-
require 'active_support/all'
|
43
|
-
|
44
|
-
Benchmark.driver do |x|
|
45
|
-
array = []
|
46
|
-
x.report('blank?') { array.blank? }
|
47
|
-
x.report('empty?') { array.empty? }
|
48
|
-
x.compare!
|
49
|
-
end
|
50
|
-
```
|
51
|
-
|
52
|
-
### Ruby Interface: Low Overhead Mode
|
37
|
+
### Ruby Interface
|
53
38
|
|
54
39
|
This interface generates code to profile with low overhead and executes it.
|
55
40
|
|
56
41
|
```rb
|
57
|
-
require '
|
58
|
-
|
42
|
+
require 'benchmark_driver'
|
43
|
+
|
44
|
+
Benchmark.drive do |x|
|
45
|
+
x.prelude = <<~RUBY
|
46
|
+
require 'active_support/all'
|
47
|
+
array = []
|
48
|
+
RUBY
|
59
49
|
|
60
|
-
Benchmark.driver do |x|
|
61
|
-
x.prelude %{ array = [] }
|
62
50
|
x.report 'blank?', %{ array.blank? }
|
63
51
|
x.report 'empty?', %{ array.empty? }
|
64
52
|
end
|
@@ -67,13 +55,16 @@ end
|
|
67
55
|
or simply:
|
68
56
|
|
69
57
|
```rb
|
70
|
-
require '
|
71
|
-
require 'active_support/all'
|
58
|
+
require 'benchmark_driver'
|
72
59
|
|
73
|
-
Benchmark.
|
74
|
-
x.prelude
|
75
|
-
|
76
|
-
|
60
|
+
Benchmark.drive do |x|
|
61
|
+
x.prelude = <<~RUBY
|
62
|
+
require 'active_support/all'
|
63
|
+
array = []
|
64
|
+
RUBY
|
65
|
+
|
66
|
+
x.report %{ array.blank? }
|
67
|
+
x.report %{ array.empty? }
|
77
68
|
end
|
78
69
|
```
|
79
70
|
|
@@ -84,10 +75,14 @@ With `benchmark-driver` command, you can describe benchmark with YAML input.
|
|
84
75
|
```
|
85
76
|
$ benchmark-driver -h
|
86
77
|
Usage: benchmark-driver [options] [YAML]
|
87
|
-
-
|
88
|
-
|
89
|
-
-
|
90
|
-
|
78
|
+
-r, --runner [TYPE] Specify runner type: ips, time, memory (default: ips)
|
79
|
+
-o, --output [TYPE] Specify output type: compare, simple, markdown (default: compare)
|
80
|
+
-e, --executables [EXECS] Ruby executables (e1::path1,arg1,...; e2::path2,arg2;...)
|
81
|
+
--rbenv [VERSIONS] Ruby executables in rbenv (x.x.x,arg1,...;y.y.y,arg2,...;...)
|
82
|
+
--repeat-count [NUM] Try benchmark NUM times and use the fastest result (TODO)
|
83
|
+
--bundler Install and use gems specified in Gemfile
|
84
|
+
--filter [REGEXP] Filter out benchmarks with given regexp
|
85
|
+
--run-duration [SECONDS] Warmup esitmates loop_count to run for this duration (default: 3)
|
91
86
|
```
|
92
87
|
|
93
88
|
#### Running single script
|
@@ -104,16 +99,17 @@ benchmark: erb.result
|
|
104
99
|
you can benchmark the script with multiple ruby executables.
|
105
100
|
|
106
101
|
```
|
107
|
-
$
|
102
|
+
$ benchmark-driver example_single.yml --rbenv '2.4.1;2.5.0'
|
108
103
|
Warming up --------------------------------------
|
109
|
-
erb.result
|
104
|
+
erb.result 71.683k i/s
|
110
105
|
Calculating -------------------------------------
|
111
|
-
2.4.2
|
112
|
-
erb.result
|
106
|
+
2.4.1 2.5.0
|
107
|
+
erb.result 72.387k 75.046k i/s - 215.049k times in 2.970833s 2.865581s
|
113
108
|
|
114
109
|
Comparison:
|
115
|
-
|
116
|
-
|
110
|
+
erb.result
|
111
|
+
2.5.0: 75045.5 i/s
|
112
|
+
2.4.1: 72386.8 i/s - 1.04x slower
|
117
113
|
```
|
118
114
|
|
119
115
|
#### Running multiple scripts
|
@@ -133,20 +129,23 @@ benchmark:
|
|
133
129
|
you can benchmark the scripts with multiple ruby executables.
|
134
130
|
|
135
131
|
```
|
136
|
-
$
|
132
|
+
$ benchmark-driver example_multi.yml --rbenv '2.4.1;2.5.0'
|
137
133
|
Warming up --------------------------------------
|
138
|
-
join
|
139
|
-
str-interp
|
134
|
+
join 2.509M i/s
|
135
|
+
str-interp 1.772M i/s
|
140
136
|
Calculating -------------------------------------
|
141
|
-
2.4.2
|
142
|
-
join
|
143
|
-
str-interp
|
137
|
+
2.4.1 2.5.0
|
138
|
+
join 2.661M 2.863M i/s - 7.527M times in 2.828771s 2.629191s
|
139
|
+
str-interp 1.890M 3.258M i/s - 5.315M times in 2.812240s 1.630997s
|
144
140
|
|
145
141
|
Comparison:
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
142
|
+
join
|
143
|
+
2.5.0: 2862755.1 i/s
|
144
|
+
2.4.1: 2660777.4 i/s - 1.08x slower
|
145
|
+
|
146
|
+
str-interp
|
147
|
+
2.5.0: 3258489.7 i/s
|
148
|
+
2.4.1: 1889805.6 i/s - 1.72x slower
|
150
149
|
```
|
151
150
|
|
152
151
|
## Contributing
|
data/benchmark_driver.gemspec
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
lib = File.expand_path('../lib', __FILE__)
|
2
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
-
require '
|
3
|
+
require 'benchmark_driver/version'
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = 'benchmark_driver'
|
7
|
-
spec.version =
|
7
|
+
spec.version = BenchmarkDriver::VERSION
|
8
8
|
spec.authors = ['Takashi Kokubun']
|
9
9
|
spec.email = ['takashikkbn@gmail.com']
|
10
10
|
|
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.bindir = 'exe'
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ['lib']
|
22
|
+
spec.required_ruby_version = '>= 2.1.0'
|
22
23
|
|
23
24
|
spec.add_development_dependency 'bundler'
|
24
25
|
spec.add_development_dependency 'rake'
|
data/bin/console
CHANGED
@@ -1,14 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'benchmark_driver'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
-
# require "pry"
|
11
|
-
# Pry.start
|
12
|
-
|
13
|
-
require "irb"
|
14
|
-
IRB.start(__FILE__)
|
6
|
+
require 'pry'
|
7
|
+
Pry.start
|
data/examples/exec_blank.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require '
|
1
|
+
require 'benchmark_driver'
|
2
2
|
|
3
|
-
Benchmark.driver(
|
3
|
+
Benchmark.driver(output: :simple) do |x|
|
4
4
|
x.prelude <<-EOS
|
5
5
|
class Array
|
6
6
|
alias_method :blank?, :empty?
|
@@ -9,5 +9,4 @@ Benchmark.driver(runner: :exec) do |x|
|
|
9
9
|
EOS
|
10
10
|
x.report %{ array.empty? }
|
11
11
|
x.report %{ array.blank? }
|
12
|
-
x.compare!
|
13
12
|
end
|
data/exe/benchmark-driver
CHANGED
@@ -1,110 +1,101 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
$:.unshift File.expand_path('../lib', __dir__)
|
3
3
|
|
4
|
-
require '
|
5
|
-
require 'benchmark/driver/yaml_parser'
|
4
|
+
require 'benchmark_driver'
|
6
5
|
require 'optparse'
|
7
6
|
require 'yaml'
|
8
7
|
|
9
|
-
|
8
|
+
|
10
9
|
# Parse command line options
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
options[:execs] << Benchmark::Driver::Configuration::Executable.parse(name_path)
|
10
|
+
config = BenchmarkDriver::Config.new.tap do |c|
|
11
|
+
executables = []
|
12
|
+
bundler = false
|
13
|
+
parser = OptionParser.new do |o|
|
14
|
+
o.banner = "Usage: #{File.basename($0, '.*')} [options] [YAML]"
|
15
|
+
o.on('-r', '--runner [TYPE]', 'Specify runner type: ips, time, memory (default: ips)') do |d|
|
16
|
+
abort '-r, --runner must take argument but not given' if d.nil?
|
17
|
+
c.runner_type = d
|
20
18
|
end
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
options[:execs] ||= []
|
25
|
-
r.split(';').each do |spec|
|
26
|
-
options[:execs] << Benchmark::Driver::Configuration::Executable.parse_rbenv(spec)
|
19
|
+
o.on('-o', '--output [TYPE]', 'Specify output type: compare, simple, markdown (default: compare)') do |out|
|
20
|
+
abort '-o, --output must take argument but not given' if out.nil?
|
21
|
+
c.output_type = out
|
27
22
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
23
|
+
o.on('-e', '--executables [EXECS]', 'Ruby executables (e1::path1,arg1,...; e2::path2,arg2;...)') do |e|
|
24
|
+
abort '--executable must take argument but not given' if e.nil?
|
25
|
+
e.split(';').each do |name_path|
|
26
|
+
name, path = name_path.split('::', 2)
|
27
|
+
command = (path || name).split(',') # if `::` is not given, regard whole string as path
|
28
|
+
command[0] = File.expand_path(command[0])
|
29
|
+
executables << BenchmarkDriver::Config::Executable.new(name: name, command: command)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
o.on('--rbenv [VERSIONS]', 'Ruby executables in rbenv (x.x.x,arg1,...;y.y.y,arg2,...;...)') do |r|
|
33
|
+
abort '--rbenv must take argument but not given' if r.nil?
|
34
|
+
r.split(';').each do |spec|
|
35
|
+
version, *args = spec.split(',')
|
36
|
+
executables << BenchmarkDriver::Config::Executable.new(
|
37
|
+
name: version,
|
38
|
+
command: [BenchmarkDriver::Rbenv.ruby_path(version), *args],
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
o.on('--repeat-count [NUM]', 'Try benchmark NUM times and use the fastest result (TODO)') do |v|
|
43
|
+
begin
|
44
|
+
c.repeat_count = Integer(v)
|
45
|
+
rescue ArgumentError
|
46
|
+
abort "-r, --repeat-count must take Integer, but got #{v.inspect}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
o.on('--bundler', 'Install and use gems specified in Gemfile') do |v|
|
50
|
+
bundler = v
|
51
|
+
end
|
52
|
+
o.on('--filter [REGEXP]', 'Filter out benchmarks with given regexp') do |v|
|
53
|
+
c.filters << Regexp.compile(v)
|
54
|
+
end
|
55
|
+
o.on('--run-duration [SECONDS]', 'Warmup esitmates loop_count to run for this duration (default: 3)') do |v|
|
56
|
+
begin
|
57
|
+
c.run_duration = Integer(v)
|
58
|
+
rescue ArgumentError
|
59
|
+
abort "--run-duration must take Integer, but got #{v.inspect}"
|
60
|
+
end
|
41
61
|
end
|
42
62
|
end
|
43
|
-
|
44
|
-
|
45
|
-
|
63
|
+
c.paths = parser.parse!(ARGV)
|
64
|
+
if c.paths.empty?
|
65
|
+
abort "No YAML file is specified!\n\n#{parser.help}"
|
46
66
|
end
|
47
|
-
|
48
|
-
|
67
|
+
|
68
|
+
# Configs that need to be set lazily
|
69
|
+
unless executables.empty?
|
70
|
+
c.executables = executables
|
49
71
|
end
|
50
|
-
|
51
|
-
|
72
|
+
if bundler
|
73
|
+
c.executables.each do |exec|
|
74
|
+
exec.command << '-rbundler/setup'
|
75
|
+
end
|
52
76
|
end
|
53
|
-
|
54
|
-
|
55
|
-
if args.empty?
|
56
|
-
abort "No YAML file is specified!\n\n#{parser.help}"
|
77
|
+
|
78
|
+
c.freeze
|
57
79
|
end
|
58
80
|
|
59
|
-
#
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
yaml = YAML.load(File.read(path))
|
64
|
-
Benchmark::Driver::Configuration.symbolize_keys!(yaml)
|
81
|
+
# Parse benchmark job definitions
|
82
|
+
jobs = config.paths.flat_map do |path|
|
83
|
+
job = YAML.load(File.read(path))
|
84
|
+
job = { 'type' => config.runner_type }.merge!(job)
|
65
85
|
|
66
86
|
begin
|
67
|
-
|
87
|
+
BenchmarkDriver::JobParser.parse(job)
|
68
88
|
rescue ArgumentError
|
69
89
|
$stderr.puts "benchmark-driver: Failed to parse #{path.dump}."
|
70
90
|
$stderr.puts ' YAML format may be wrong. See error below:'
|
71
91
|
$stderr.puts
|
72
92
|
raise
|
73
93
|
end
|
74
|
-
end
|
75
|
-
|
76
|
-
|
77
|
-
# Proceed parsed options
|
78
|
-
#
|
79
|
-
config = Benchmark::Driver::Configuration.new(jobs)
|
80
|
-
config.runner_options = Benchmark::Driver::Configuration::RunnerOptions.new
|
81
|
-
config.output_options = Benchmark::Driver::Configuration::OutputOptions.new(:ips)
|
82
|
-
|
83
|
-
options.each do |key, value|
|
84
|
-
case key
|
85
|
-
when :bundler
|
86
|
-
config.runner_options.bundler = value
|
87
|
-
when :compare
|
88
|
-
config.output_options.compare = value
|
89
|
-
when :dir
|
90
|
-
dir = File.dirname(path)
|
91
|
-
config.jobs.each do |job|
|
92
|
-
job.prelude = "__dir__ = #{dir.dump}.freeze; #{job.prelude}"
|
93
|
-
end
|
94
|
-
when :execs
|
95
|
-
config.runner_options.executables = options.delete(:execs)
|
96
|
-
when :filter
|
97
|
-
filter = Regexp.compile(value)
|
98
|
-
config.jobs.select! do |job|
|
99
|
-
job.name.match(filter)
|
100
|
-
end
|
101
|
-
when :output
|
102
|
-
config.output_options.type = value.to_sym
|
103
|
-
when :repeat_count
|
104
|
-
config.runner_options.repeat_count = value
|
105
|
-
else
|
106
|
-
raise "Unhandled option: #{key.inspect}"
|
94
|
+
end.select do |job|
|
95
|
+
config.filters.all? do |filter|
|
96
|
+
job.name.match(filter)
|
107
97
|
end
|
108
98
|
end
|
109
99
|
|
110
|
-
|
100
|
+
# Run jobs
|
101
|
+
BenchmarkDriver::Runner.run(jobs, config: config)
|