benchmark_driver 0.8.6 → 0.9.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/.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 [](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)
|