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
data/examples/call.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'benchmark/driver'
|
2
|
+
|
3
|
+
Benchmark.driver do |x|
|
4
|
+
large_a = "Hellooooooooooooooooooooooooooooooooooooooooooooooooooo"
|
5
|
+
large_b = "Wooooooooooooooooooooooooooooooooooooooooooooooooooorld"
|
6
|
+
|
7
|
+
small_a = "Hello"
|
8
|
+
small_b = "World"
|
9
|
+
|
10
|
+
x.report('large') { "#{large_a}, #{large_b}!" }
|
11
|
+
x.report('small') { "#{small_a}, #{small_b}!" }
|
12
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'benchmark/driver'
|
2
|
+
require 'erb'
|
3
|
+
require 'erubi'
|
4
|
+
require 'erubis'
|
5
|
+
|
6
|
+
data = DATA.read
|
7
|
+
|
8
|
+
mod = Module.new
|
9
|
+
mod.instance_eval("def self.erb(title, content); #{ERB.new(data).src}; end", "(ERB)")
|
10
|
+
mod.instance_eval("def self.erubis(title, content); #{Erubi::Engine.new(data).src}; end", "(Erubi)")
|
11
|
+
mod.instance_eval("def self.erubi(title, content); #{Erubis::Eruby.new(data).src}; end", "(Erubis)")
|
12
|
+
|
13
|
+
title = "hello world!"
|
14
|
+
content = "hello world!\n" * 10
|
15
|
+
|
16
|
+
Benchmark.driver do |x|
|
17
|
+
x.report("ERB #{RUBY_VERSION}") { mod.erb(title, content) }
|
18
|
+
x.report("Erubis #{Erubis::VERSION}") { mod.erubis(title, content) }
|
19
|
+
x.report("Erubi #{Erubi::VERSION}") { mod.erubi(title, content) }
|
20
|
+
x.compare!
|
21
|
+
end
|
22
|
+
|
23
|
+
__END__
|
24
|
+
|
25
|
+
<html>
|
26
|
+
<head> <%= title %> </head>
|
27
|
+
<body>
|
28
|
+
<h1> <%= title %> </h1>
|
29
|
+
<p>
|
30
|
+
<%= content %>
|
31
|
+
</p>
|
32
|
+
</body>
|
33
|
+
</html>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'benchmark/driver'
|
2
|
+
|
3
|
+
Benchmark.driver do |x|
|
4
|
+
large_a = "Hellooooooooooooooooooooooooooooooooooooooooooooooooooo"
|
5
|
+
large_b = "Wooooooooooooooooooooooooooooooooooooooooooooooooooorld"
|
6
|
+
|
7
|
+
small_a = "Hello"
|
8
|
+
small_b = "World"
|
9
|
+
|
10
|
+
x.report('large') { "#{large_a}, #{large_b}!" }
|
11
|
+
x.report('small') { "#{small_a}, #{small_b}!" }
|
12
|
+
x.compare!
|
13
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'benchmark/driver'
|
2
|
+
|
3
|
+
Benchmark.driver(runner: :exec) do |x|
|
4
|
+
x.prelude = <<-EOS
|
5
|
+
class Array
|
6
|
+
alias_method :blank?, :empty?
|
7
|
+
end
|
8
|
+
array = []
|
9
|
+
EOS
|
10
|
+
|
11
|
+
x.report(script: 'array.empty?')
|
12
|
+
x.report(script: 'array.blank?')
|
13
|
+
x.compare!
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'benchmark/driver'
|
2
|
+
|
3
|
+
Benchmark.driver(runner: :exec) do |x|
|
4
|
+
x.prelude = <<-EOS
|
5
|
+
large_a = "Hellooooooooooooooooooooooooooooooooooooooooooooooooooo"
|
6
|
+
large_b = "Wooooooooooooooooooooooooooooooooooooooooooooooooooorld"
|
7
|
+
|
8
|
+
small_a = "Hello"
|
9
|
+
small_b = "World"
|
10
|
+
EOS
|
11
|
+
|
12
|
+
x.report('large', script: '"#{large_a}, #{large_b}!"')
|
13
|
+
x.report('small', script: '"#{small_a}, #{small_b}!"')
|
14
|
+
x.compare!
|
15
|
+
end
|
File without changes
|
data/exe/benchmark-driver
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
$:.unshift File.expand_path('../lib', __dir__)
|
3
3
|
|
4
|
-
require '
|
4
|
+
require 'benchmark/driver'
|
5
|
+
require 'benchmark/driver/yaml_parser'
|
5
6
|
require 'optparse'
|
6
7
|
require 'yaml'
|
7
8
|
|
@@ -10,32 +11,57 @@ args = OptionParser.new do |o|
|
|
10
11
|
o.banner = "Usage: #{File.basename($0, '.*')} [options] [YAML]"
|
11
12
|
o.on('-e', '--executables [EXECS]', 'Ruby executables (e1::path1; e2::path2; e3::path3;...)') do |e|
|
12
13
|
options[:execs] ||= []
|
13
|
-
e.split(
|
14
|
-
|
14
|
+
e.split(';').each do |name_path|
|
15
|
+
name, path = name_path.split('::', 2)
|
16
|
+
options[:execs] << Benchmark::Driver::Configuration::Executable.new(name, path || name)
|
15
17
|
end
|
16
18
|
end
|
17
|
-
o.on('
|
19
|
+
o.on('--rbenv [VERSIONS]', 'Ruby executables in rbenv (2.3.5;2.4.2;...)') do |r|
|
18
20
|
options[:execs] ||= []
|
19
|
-
r.split(
|
20
|
-
|
21
|
+
r.split(';').each do |version|
|
22
|
+
path = `RBENV_VERSION='#{version}' rbenv which ruby`.rstrip
|
23
|
+
abort "Failed to execute 'rbenv which ruby'" unless $?.success?
|
24
|
+
options[:execs] << Benchmark::Driver::Configuration::Executable.new(version, path)
|
21
25
|
end
|
22
26
|
end
|
23
|
-
o.on('-
|
24
|
-
options[:
|
25
|
-
options[:measure_num] = Integer(i) if i
|
27
|
+
o.on('-c', '--compare', 'Compare results (currently only supported in ips output)') do |v|
|
28
|
+
options[:compare] = v
|
26
29
|
end
|
27
|
-
o.on('-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
o.on('-r', '--repeat-count [NUM]', 'Try benchmark NUM times and use the fastest result') do |v|
|
31
|
+
begin
|
32
|
+
options[:repeat_count] = Integer(v)
|
33
|
+
rescue ArgumentError
|
34
|
+
abort "-r, --repeat-count must take Integer, but got #{v.inspect}"
|
35
|
+
end
|
33
36
|
end
|
34
37
|
end.parse!(ARGV)
|
35
38
|
abort "No YAML file is specified" if args.empty?
|
36
39
|
|
37
|
-
driver = Benchmark::Driver.new(options)
|
38
40
|
args.each do |yaml|
|
39
|
-
|
40
|
-
|
41
|
+
yaml = YAML.load(File.read(yaml))
|
42
|
+
Benchmark::Driver::Configuration.symbolize_keys!(yaml)
|
43
|
+
|
44
|
+
begin
|
45
|
+
config = Benchmark::Driver::YamlParser.parse(yaml)
|
46
|
+
rescue ArgumentError
|
47
|
+
$stderr.puts "benchmark-driver: Failed to parse #{yaml.dump}."
|
48
|
+
$stderr.puts ' YAML format may be wrong. See error below:'
|
49
|
+
$stderr.puts
|
50
|
+
raise
|
51
|
+
end
|
52
|
+
|
53
|
+
options.each do |key, value|
|
54
|
+
case key
|
55
|
+
when :compare
|
56
|
+
config.output_options.compare = value
|
57
|
+
when :execs
|
58
|
+
config.runner_options.executables = value
|
59
|
+
when :repeat_count
|
60
|
+
config.runner_options.repeat_count = value
|
61
|
+
else
|
62
|
+
raise "Unhandled option: #{key.inspect}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
Benchmark::Driver.run(config)
|
41
67
|
end
|
data/lib/benchmark/driver.rb
CHANGED
@@ -1,273 +1,68 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'tempfile'
|
4
|
-
|
5
|
-
class Benchmark::Driver
|
6
|
-
MEASURE_TYPES = %w[loop_count ips]
|
7
|
-
DEFAULT_LOOP_COUNT = 100_000
|
8
|
-
DEFAULT_IPS_DURATION = 1
|
9
|
-
|
10
|
-
# @param [String] measure_type - "loop_count"|"ips"
|
11
|
-
# @param [Integer,nil] measure_num - Loop count for "loop_type", duration seconds for "ips"
|
12
|
-
# @param [Array<String>] execs - ["path1", "path2"] or `["ruby1::path1", "ruby2::path2"]`
|
13
|
-
# @param [Boolean] verbose
|
14
|
-
def initialize(measure_type: 'loop_count', measure_num: nil, execs: ['ruby'], verbose: false)
|
15
|
-
unless MEASURE_TYPES.include?(measure_type)
|
16
|
-
abort "unsupported measure type: #{measure_type.dump}"
|
17
|
-
end
|
18
|
-
@measure_type = measure_type
|
19
|
-
@measure_num = measure_num
|
20
|
-
@execs = execs.map do |exec|
|
21
|
-
name, path = exec.split('::', 2)
|
22
|
-
Executable.new(name, path || name)
|
23
|
-
end
|
24
|
-
@verbose = verbose
|
25
|
-
end
|
26
|
-
|
27
|
-
# @param [Hash] root_hash
|
28
|
-
def run(root_hash)
|
29
|
-
root = BenchmarkRoot.new(Hash[root_hash.map { |k, v| [k.to_sym, v] }])
|
30
|
-
|
31
|
-
results = root.benchmarks.map do |benchmark|
|
32
|
-
metrics_by_exec = {}
|
33
|
-
iterations = calc_iterations(@execs.first, benchmark)
|
34
|
-
@execs.each do |exec|
|
35
|
-
if @verbose
|
36
|
-
puts "--- Running #{benchmark.name.dump} with #{exec.name.dump} #{iterations} times ---"
|
37
|
-
puts "#{benchmark.benchmark_script(iterations)}\n"
|
38
|
-
end
|
39
|
-
elapsed_time = run_benchmark(exec, benchmark, iterations)
|
40
|
-
metrics_by_exec[exec] = BenchmarkMetrics.new(iterations, elapsed_time)
|
41
|
-
end
|
42
|
-
BenchmarkResult.new(benchmark.name, metrics_by_exec)
|
43
|
-
end
|
44
|
-
puts if @verbose
|
45
|
-
|
46
|
-
case @measure_type
|
47
|
-
when 'loop_count'
|
48
|
-
LoopCountReporter.report(@execs, results)
|
49
|
-
when 'ips'
|
50
|
-
IpsReporter.report(@execs, results)
|
51
|
-
else
|
52
|
-
raise "unexpected measure type: #{@measure_type.dump}"
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
private
|
57
|
-
|
58
|
-
# Estimate iterations to finish benchmark within `@duration`.
|
59
|
-
def calc_iterations(exec, benchmark)
|
60
|
-
case @measure_type
|
61
|
-
when 'loop_count'
|
62
|
-
@measure_num || benchmark.loop_count || DEFAULT_LOOP_COUNT
|
63
|
-
when 'ips'
|
64
|
-
# TODO: Change to try from 1, 10, 100 ...
|
65
|
-
base = 1000
|
66
|
-
time = run_benchmark(exec, benchmark, base)
|
67
|
-
duration = @measure_num || DEFAULT_IPS_DURATION
|
68
|
-
(duration / time * base).to_i
|
69
|
-
else
|
70
|
-
raise "unexpected measure type: #{@measure_type.dump}"
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def run_benchmark(exec, benchmark, iterations)
|
75
|
-
# TODO: raise error if negative
|
76
|
-
measure_script(exec.path, benchmark.benchmark_script(iterations)) -
|
77
|
-
measure_script(exec.path, benchmark.overhead_script(iterations))
|
78
|
-
end
|
79
|
-
|
80
|
-
def measure_script(ruby, script)
|
81
|
-
Tempfile.create(File.basename(__FILE__)) do |f|
|
82
|
-
f.write(script)
|
83
|
-
f.close
|
84
|
-
|
85
|
-
cmd = "#{ruby} #{f.path}"
|
86
|
-
Benchmark.measure { system(cmd, out: File::NULL) }.real
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
class BenchmarkRoot
|
91
|
-
# @param [String] name
|
92
|
-
# @param [String] prelude
|
93
|
-
# @param [Integer,nil] loop_count
|
94
|
-
# @param [String,nil] benchmark - For running single instant benchmark
|
95
|
-
# @param [Array<Hash>] benchmarks - For running multiple benchmarks
|
96
|
-
def initialize(name:, prelude: '', loop_count: nil, benchmark: nil, benchmarks: [])
|
97
|
-
if benchmark
|
98
|
-
unless benchmarks.empty?
|
99
|
-
raise ArgumentError.new("Only either :benchmark or :benchmarks can be specified")
|
100
|
-
end
|
101
|
-
@benchmarks = [BenchmarkScript.new(name: name, prelude: prelude, benchmark: benchmark)]
|
102
|
-
else
|
103
|
-
@benchmarks = benchmarks.map do |hash|
|
104
|
-
BenchmarkScript.new(Hash[hash.map { |k, v| [k.to_sym, v] }]).tap do |b|
|
105
|
-
b.inherit_root(prelude: prelude, loop_count: loop_count)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
# @return [Array<BenchmarkScript>]
|
112
|
-
attr_reader :benchmarks
|
113
|
-
end
|
114
|
-
|
115
|
-
class BenchmarkScript
|
116
|
-
# @param [String] name
|
117
|
-
# @param [String] prelude
|
118
|
-
# @param [String] benchmark
|
119
|
-
def initialize(name:, prelude: '', loop_count: nil, benchmark:)
|
120
|
-
@name = name
|
121
|
-
@prelude = prelude
|
122
|
-
@loop_count = loop_count
|
123
|
-
@benchmark = benchmark
|
124
|
-
end
|
125
|
-
|
126
|
-
# @return [String]
|
127
|
-
attr_reader :name
|
128
|
-
|
129
|
-
# @return [Integer]
|
130
|
-
attr_reader :loop_count
|
131
|
-
|
132
|
-
def inherit_root(prelude:, loop_count:)
|
133
|
-
@prelude = "#{prelude}\n#{@prelude}"
|
134
|
-
if @loop_count.nil? && loop_count
|
135
|
-
@loop_count = loop_count
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
def overhead_script(iterations)
|
140
|
-
<<-RUBY
|
141
|
-
#{@prelude}
|
142
|
-
__benchmark_driver_i = 0
|
143
|
-
while __benchmark_driver_i < #{iterations}
|
144
|
-
__benchmark_driver_i += 1
|
145
|
-
end
|
146
|
-
RUBY
|
147
|
-
end
|
148
|
-
|
149
|
-
def benchmark_script(iterations)
|
150
|
-
<<-RUBY
|
151
|
-
#{@prelude}
|
152
|
-
__benchmark_driver_i = 0
|
153
|
-
while __benchmark_driver_i < #{iterations}
|
154
|
-
__benchmark_driver_i += 1
|
155
|
-
#{@benchmark}
|
156
|
-
end
|
157
|
-
RUBY
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
class BenchmarkResult < Struct.new(
|
162
|
-
:name, # @param [String]
|
163
|
-
:metrics_by_exec, # @param [Hash{ Executable => BenchmarkMetrics }]
|
164
|
-
)
|
165
|
-
def iterations_of(exec)
|
166
|
-
metrics_by_exec.fetch(exec).iterations
|
167
|
-
end
|
168
|
-
|
169
|
-
def elapsed_time_of(exec)
|
170
|
-
metrics_by_exec.fetch(exec).elapsed_time
|
171
|
-
end
|
172
|
-
|
173
|
-
def ips_of(exec)
|
174
|
-
iterations_of(exec) / elapsed_time_of(exec)
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
class BenchmarkMetrics < Struct.new(
|
179
|
-
:iterations, # @param [Integer]
|
180
|
-
:elapsed_time, # @param [Float] - Elapsed time in seconds
|
181
|
-
)
|
182
|
-
end
|
183
|
-
|
184
|
-
class Executable < Struct.new(
|
185
|
-
:name, # @param [String]
|
186
|
-
:path, # @param [String]
|
187
|
-
)
|
188
|
-
end
|
189
|
-
|
190
|
-
module LoopCountReporter
|
1
|
+
module Benchmark
|
2
|
+
module Driver
|
191
3
|
class << self
|
192
|
-
#
|
193
|
-
# @param [
|
194
|
-
def
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
4
|
+
# Main function which is used by both RubyDriver and YamlDriver.
|
5
|
+
# @param [Benchmark::Driver::Configuration] config
|
6
|
+
def run(config)
|
7
|
+
validate_config(config)
|
8
|
+
|
9
|
+
runner_class = Runner.find(config.runner_options.type)
|
10
|
+
output_class = Output.find(config.output_options.type)
|
11
|
+
|
12
|
+
missing_fields = output_class::REQUIRED_FIELDS - runner_class::SUPPORTED_FIELDS
|
13
|
+
unless missing_fields.empty?
|
14
|
+
raise ArgumentError.new(
|
15
|
+
"#{output_class.name} requires #{missing_fields.inspect} fields "\
|
16
|
+
"which are not supported by #{runner_class.name}. Try using another runner."
|
17
|
+
)
|
204
18
|
end
|
205
|
-
puts
|
206
19
|
|
207
|
-
|
208
|
-
|
20
|
+
without_stdout_buffering do
|
21
|
+
runner = runner_class.new(
|
22
|
+
config.runner_options,
|
23
|
+
output: output_class.new(
|
24
|
+
jobs: config.jobs,
|
25
|
+
executables: config.runner_options.executables,
|
26
|
+
options: config.output_options,
|
27
|
+
),
|
28
|
+
)
|
29
|
+
runner.run(config)
|
209
30
|
end
|
31
|
+
rescue Benchmark::Driver::Error => e
|
32
|
+
$stderr.puts "\n\nFailed to execute benchmark!\n\n#{e.class.name}:\n #{e.message}"
|
33
|
+
exit 1
|
210
34
|
end
|
211
35
|
|
212
36
|
private
|
213
37
|
|
214
|
-
def
|
215
|
-
|
216
|
-
|
38
|
+
def validate_config(config)
|
39
|
+
# TODO: make sure all scripts are the same class
|
40
|
+
end
|
217
41
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
42
|
+
# benchmark_driver ouputs logs ASAP. This enables sync flag for it.
|
43
|
+
#
|
44
|
+
# Currently benchmark_driver supports only output to stdout.
|
45
|
+
# In future exetension, this may be included in Output plugins.
|
46
|
+
def without_stdout_buffering
|
47
|
+
sync, $stdout.sync = $stdout.sync, true
|
48
|
+
yield
|
49
|
+
ensure
|
50
|
+
$stdout.sync = sync
|
227
51
|
end
|
228
52
|
end
|
229
53
|
end
|
230
54
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
def report(execs, results)
|
236
|
-
puts "Result -------------------------------------------"
|
237
|
-
puts "#{' ' * 16} #{execs.map { |e| "%13s" % e.name }.join(' ')}"
|
238
|
-
|
239
|
-
results.each do |result|
|
240
|
-
print '%16s ' % result.name
|
241
|
-
puts execs.map { |exec|
|
242
|
-
"%13s" % ("%.1f i/s" % result.ips_of(exec))
|
243
|
-
}.join(' ')
|
244
|
-
end
|
245
|
-
puts
|
246
|
-
|
247
|
-
if execs.size > 1
|
248
|
-
compare(execs, results)
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
private
|
253
|
-
|
254
|
-
def compare(execs, results)
|
255
|
-
results.each do |result|
|
256
|
-
puts "Comparison: #{result.name}"
|
55
|
+
# RubyDriver entrypoint.
|
56
|
+
def self.driver(*args, &block)
|
57
|
+
dsl = Driver::RubyDslParser.new(*args)
|
58
|
+
block.call(dsl)
|
257
59
|
|
258
|
-
|
259
|
-
first = sorted.first
|
260
|
-
|
261
|
-
sorted.each do |exec|
|
262
|
-
if exec == first
|
263
|
-
puts "%16s: %12s i/s" % [first.name, "%.1f" % result.ips_of(first)]
|
264
|
-
else
|
265
|
-
puts "%16s: %12s i/s - %.2fx slower" % [exec.name, "%.1f" % result.ips_of(exec), result.ips_of(first) / result.ips_of(exec)]
|
266
|
-
end
|
267
|
-
end
|
268
|
-
puts
|
269
|
-
end
|
270
|
-
end
|
271
|
-
end
|
60
|
+
Driver.run(dsl.configuration)
|
272
61
|
end
|
273
62
|
end
|
63
|
+
|
64
|
+
require 'benchmark/output'
|
65
|
+
require 'benchmark/runner'
|
66
|
+
require 'benchmark/driver/error'
|
67
|
+
require 'benchmark/driver/ruby_dsl_parser'
|
68
|
+
require 'benchmark/driver/version'
|