benchmark_driver 0.5.1 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 129876bda34ed8e37319e40790c1b31c65428ad62ce0b1b71719b55b609f5368
4
- data.tar.gz: b0cf2334ef7b4a7ab495907481f01dad6bc619a696106e52a1ef8473d8436a74
3
+ metadata.gz: 47b335872c19aca072e3990d807767428113c3f57fb7b701fd6df4769c94ecf2
4
+ data.tar.gz: e1a86a2541e681b2a04db79912da4c079426dd3aa843bc0959edf3321d2fe768
5
5
  SHA512:
6
- metadata.gz: a0fec38aee5a87e31db94a6f5f93ef98343cb01e02be4f690cba7e39a055515fe162ba029eceb062655fc7ebd11dd07be1ab7149d3b584f4638374216ce07a02
7
- data.tar.gz: 66cd0347f55008f753fa0143226c9ff2a6938bb0bd92fd8606c11eba1cfb593a370ed68f44381e123048630177b4bb88d88a2782985eb5a7f1d9a914553c44fb
6
+ metadata.gz: e015bc42e98d81dbb6c855159ecee0367fcb2f737b5c0d37dff43bd972c456d97c79c9c00c00034d153fdb1471f3f71cf55ab3a1b0d5e185d1d6d56fdb59ec96
7
+ data.tar.gz: bd31b303ef412073906c287b977ac82c4813260239b334824ce419dd3140bfbb76861e3280dee091b41dc1ae2d9fe1cd75cc6234dc5c4e1631c7809a5f27fb3a
data/.travis.yml CHANGED
@@ -11,5 +11,4 @@ branches:
11
11
  - master
12
12
  before_install: gem install bundler -v 1.15.4
13
13
  script:
14
- - bundle exec rake ruby_examples
15
14
  - bundle exec rake yaml_examples
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # v0.6.0
2
+
3
+ - Drop support of Ruby interface
4
+ - Drop support of specifying runner, output options on YAML definition
5
+ - Allow specifying output type on CLI
6
+ - Run multiple benchmark files at once, instead of sequentially executing them
7
+
1
8
  # v0.5.1
2
9
 
3
10
  - Fix a bug that fails to run multiple Ruby binaries when multiple YAML files are specified
data/README.md CHANGED
@@ -18,12 +18,11 @@ NOTE: Pending ones are ~slashed~.
18
18
  ### Pluggable & Fully Featured
19
19
 
20
20
  - Flexible and real-time output format in ips, execution time, ~markdown table~, etc.
21
- - Runner and output are all pluggable
21
+ - Output format is pluggable
22
22
  - ~Integrated benchmark support using external libraries~
23
23
 
24
24
  ### Flexible Interface
25
25
 
26
- - Ruby interface similar to benchmark stdlib, benchmark-ips
27
26
  - YAML input to easily manage structured benchmark set
28
27
  - Comparing multiple Ruby binaries, even with miniruby
29
28
 
@@ -35,58 +34,6 @@ $ gem install benchmark_driver
35
34
 
36
35
  ## Usage
37
36
 
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
37
  With `benchmark-driver` command, you can describe benchmark with YAML input.
91
38
 
92
39
  ```
@@ -98,7 +45,7 @@ Usage: benchmark-driver [options] [YAML]
98
45
  -r, --repeat-count [NUM] Try benchmark NUM times and use the fastest result
99
46
  ```
100
47
 
101
- #### Running single script
48
+ ### Running single script
102
49
 
103
50
  With following `example_single.yml`,
104
51
 
@@ -124,7 +71,7 @@ Comparison:
124
71
  erb.result (2.4.2): 109268.4 i/s - 1.13x slower
125
72
  ```
126
73
 
127
- #### Running multiple scripts
74
+ ### Running multiple scripts
128
75
 
129
76
  One YAML file can contain multiple benchmark scripts.
130
77
  With following `example_multi.yml`,
@@ -159,15 +106,14 @@ Comparison:
159
106
 
160
107
  ## TODO
161
108
  ### Runner
162
- - [x] Call
163
109
  - [x] Exec
164
110
  - [ ] Eval
165
111
 
166
112
  ### Output
167
113
  - [x] IPS
168
114
  - [x] Time
115
+ - [x] Memory
169
116
  - [ ] CPU/System/Real Time
170
- - [ ] Memory
171
117
  - [ ] Markdown Table
172
118
 
173
119
  ## Contributing
data/Rakefile CHANGED
@@ -1,15 +1,6 @@
1
1
  require 'bundler/gem_tasks'
2
2
  require 'shellwords'
3
3
 
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
12
-
13
4
  task :yaml_examples do
14
5
  Dir.glob(File.expand_path('./examples/yaml/*.yml', __dir__)).sort.each do |file|
15
6
  Bundler.with_clean_env do
@@ -19,4 +10,4 @@ task :yaml_examples do
19
10
  end
20
11
  end
21
12
 
22
- task default: [:ruby_examples, :yaml_examples]
13
+ task default: :yaml_examples
@@ -1,3 +1,2 @@
1
- output: time
2
1
  benchmark:
3
2
  bm_vm2_array: a = [1,2,3,4,5,6,7,8,9,10]
data/exe/benchmark-driver CHANGED
@@ -3,10 +3,14 @@ $:.unshift File.expand_path('../lib', __dir__)
3
3
 
4
4
  require 'benchmark/driver'
5
5
  require 'benchmark/driver/bundle_installer'
6
+ require 'benchmark/driver/configuration'
6
7
  require 'benchmark/driver/yaml_parser'
7
8
  require 'optparse'
8
9
  require 'yaml'
9
10
 
11
+ #
12
+ # Parse command line options
13
+ #
10
14
  options = {}
11
15
  parser = OptionParser.new do |o|
12
16
  o.banner = "Usage: #{File.basename($0, '.*')} [options] [YAML]"
@@ -28,6 +32,10 @@ parser = OptionParser.new do |o|
28
32
  options[:execs] << Benchmark::Driver::Configuration::Executable.new(version, [path, *args])
29
33
  end
30
34
  end
35
+ o.on('-o', '--output [TYPE]', 'Specify output type (ips, time, memory)') do |t|
36
+ abort '-o, --output must take argument but not given' if t.nil?
37
+ options[:output] = t
38
+ end
31
39
  o.on('-c', '--compare', 'Compare results (currently only supported in ips output)') do |v|
32
40
  options[:compare] = v
33
41
  end
@@ -54,51 +62,61 @@ if args.empty?
54
62
  abort "No YAML file is specified!\n\n#{parser.help}"
55
63
  end
56
64
 
57
- args.each do |path|
65
+ #
66
+ # Parse benchmark definitions
67
+ #
68
+ jobs = args.flat_map do |path|
58
69
  yaml = YAML.load(File.read(path))
59
70
  Benchmark::Driver::Configuration.symbolize_keys!(yaml)
60
71
 
61
72
  begin
62
- config = Benchmark::Driver::YamlParser.parse(yaml)
73
+ Benchmark::Driver::YamlParser.parse(yaml)
63
74
  rescue ArgumentError
64
75
  $stderr.puts "benchmark-driver: Failed to parse #{yaml.dump}."
65
76
  $stderr.puts ' YAML format may be wrong. See error below:'
66
77
  $stderr.puts
67
78
  raise
68
79
  end
80
+ end
69
81
 
70
- opts = options.dup
82
+ #
83
+ # Proceed parsed options
84
+ #
85
+ config = Benchmark::Driver::Configuration.new(jobs)
86
+ config.runner_options = Benchmark::Driver::Configuration::RunnerOptions.new(:exec)
87
+ config.output_options = Benchmark::Driver::Configuration::OutputOptions.new(:ips)
71
88
 
89
+ if options.key?(:execs)
72
90
  # Proceed execs first for --bundler
73
- if opts.key?(:execs)
74
- config.runner_options.executables = opts.delete(:execs)
75
- end
91
+ config.runner_options.executables = options.delete(:execs)
92
+ end
76
93
 
77
- opts.each do |key, value|
78
- case key
79
- when :bundler
80
- config.runner_options.executables.each do |executable|
81
- Benchmark::Driver::BundleInstaller.bundle_install_for(executable)
82
- executable.command << '-rbundler/setup'
83
- end
84
- when :compare
85
- config.output_options.compare = value
86
- when :dir
87
- dir = File.dirname(path)
88
- config.jobs.each do |job|
89
- job.prelude = "__dir__ = #{dir.dump}.freeze; #{job.prelude}"
90
- end
91
- when :filter
92
- filter = Regexp.compile(value)
93
- config.jobs.select! do |job|
94
- job.name.match(filter)
95
- end
96
- when :repeat_count
97
- config.runner_options.repeat_count = value
98
- else
99
- raise "Unhandled option: #{key.inspect}"
94
+ options.each do |key, value|
95
+ case key
96
+ when :bundler
97
+ config.runner_options.executables.each do |executable|
98
+ Benchmark::Driver::BundleInstaller.bundle_install_for(executable)
99
+ executable.command << '-rbundler/setup'
100
100
  end
101
+ when :compare
102
+ config.output_options.compare = value
103
+ when :dir
104
+ dir = File.dirname(path)
105
+ config.jobs.each do |job|
106
+ job.prelude = "__dir__ = #{dir.dump}.freeze; #{job.prelude}"
107
+ end
108
+ when :filter
109
+ filter = Regexp.compile(value)
110
+ config.jobs.select! do |job|
111
+ job.name.match(filter)
112
+ end
113
+ when :output
114
+ config.output_options.type = value.to_sym
115
+ when :repeat_count
116
+ config.runner_options.repeat_count = value
117
+ else
118
+ raise "Unhandled option: #{key.inspect}"
101
119
  end
102
-
103
- Benchmark::Driver.run(config)
104
120
  end
121
+
122
+ Benchmark::Driver.run(config)
@@ -1,7 +1,7 @@
1
1
  module Benchmark
2
2
  module Driver
3
3
  class << self
4
- # Main function which is used by both RubyDriver and YamlDriver.
4
+ # Main function which is used by exe/benchmark-driver.
5
5
  # @param [Benchmark::Driver::Configuration] config
6
6
  def run(config)
7
7
  validate_config(config)
@@ -51,18 +51,9 @@ module Benchmark
51
51
  end
52
52
  end
53
53
  end
54
-
55
- # RubyDriver entrypoint.
56
- def self.driver(*args, &block)
57
- dsl = Driver::RubyDslParser.new(*args)
58
- block.call(dsl)
59
-
60
- Driver.run(dsl.configuration)
61
- end
62
54
  end
63
55
 
64
56
  require 'benchmark/output'
65
57
  require 'benchmark/runner'
66
58
  require 'benchmark/driver/error'
67
- require 'benchmark/driver/ruby_dsl_parser'
68
59
  require 'benchmark/driver/version'
@@ -1,5 +1,5 @@
1
1
  module Benchmark
2
2
  module Driver
3
- VERSION = '0.5.1'
3
+ VERSION = '0.6.0'
4
4
  end
5
5
  end
@@ -1,67 +1,19 @@
1
1
  module Benchmark::Driver::YamlParser
2
- DEFAULT_RUNNER = :exec # In YamlParser, we can't use :call.
3
- DEFAULT_OUTPUT = :ips
4
-
5
2
  class << self
6
3
  # @param [String] prelude
7
4
  # @param [Integer,nil] loop_count
8
5
  # @param [String,Array<String,Hash{ Symbol => String }>,Hash{ Symbol => String }] benchmark
9
- # @param [String,Symbol,Hash{ Symbol => Integer,TrueClass,FalseClass }] runner
10
- # @param [String,Symbol,Hash{ Symbol => Integer,TrueClass,FalseClass }] output
11
- # @return [Benchmark::Driver::Configuration]
12
- def parse(prelude: '', loop_count: nil, benchmark:, runner: {}, output: {})
6
+ # @return [Array<Benchmark::Driver::Configuration::Job>]
7
+ def parse(prelude: '', loop_count: nil, benchmark:)
13
8
  jobs = parse_benchmark(benchmark)
14
9
  jobs.each do |job|
15
10
  job.prelude = prelude
16
11
  job.loop_count ||= loop_count
17
12
  end
18
-
19
- config = Benchmark::Driver::Configuration.new(jobs)
20
- config.runner_options = parse_runner(runner)
21
- config.output_options = parse_output(output)
22
- config
23
13
  end
24
14
 
25
15
  private
26
16
 
27
- # @param [String,Symbol,Hash{ Symbol => Integer,TrueClass,FalseClass }] runner
28
- def parse_runner(runner)
29
- case runner
30
- when String, Symbol
31
- Benchmark::Driver::Configuration::RunnerOptions.new(runner.to_sym)
32
- when Hash
33
- parse_runner_options(runner)
34
- else
35
- raise ArgumentError.new("Expected String, Symbol or Hash in runner, but got: #{runner.inspect}")
36
- end
37
- end
38
-
39
- def parse_runner_options(type: DEFAULT_RUNNER, repeat_count: nil)
40
- Benchmark::Driver::Configuration::RunnerOptions.new.tap do |r|
41
- r.type = type.to_sym
42
- r.repeat_count = Integer(repeat_count) if repeat_count
43
- end
44
- end
45
-
46
- # @param [String,Symbol,Hash{ Symbol => Integer,TrueClass,FalseClass }] output
47
- def parse_output(output)
48
- case output
49
- when String, Symbol
50
- Benchmark::Driver::Configuration::OutputOptions.new(output.to_sym)
51
- when Hash
52
- parse_output_options(output)
53
- else
54
- raise ArgumentError.new("Expected String, Symbol or Hash in output, but got: #{output.inspect}")
55
- end
56
- end
57
-
58
- def parse_output_options(type: DEFAULT_OUTPUT, compare: false)
59
- Benchmark::Driver::Configuration::OutputOptions.new.tap do |r|
60
- r.type = type.to_sym
61
- r.compare = compare
62
- end
63
- end
64
-
65
17
  # Parse "benchmark" declarative. This may have multiple benchmarks.
66
18
  # @param [String,Array<String,Hash{ Symbol => String }>,Hash{ Symbol => String }] benchmark
67
19
  def parse_benchmark(benchmark)
@@ -2,6 +2,8 @@ module Benchmark::Runner
2
2
  # Benchmark::Runner is pluggable.
3
3
  # Create `Benchmark::Runner::FooBar` as benchmark-runner-foo_bar.gem and specify `runner: foo_bar`.
4
4
  #
5
+ # Currently this has no options other than Exec, but this will have Eval for sure.
6
+ #
5
7
  # @param [Symbol] name
6
8
  def self.find(name)
7
9
  class_name = Benchmark::Driver::Configuration.camelize(name.to_s)
@@ -9,5 +11,4 @@ module Benchmark::Runner
9
11
  end
10
12
  end
11
13
 
12
- require 'benchmark/runner/call'
13
14
  require 'benchmark/runner/exec'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: benchmark_driver
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Takashi Kokubun
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-12-14 00:00:00.000000000 Z
11
+ date: 2017-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -56,20 +56,11 @@ files:
56
56
  - benchmark_driver.gemspec
57
57
  - bin/console
58
58
  - bin/setup
59
- - examples/call.rb
60
- - examples/call_blank.rb
61
- - examples/call_erb.rb
62
- - examples/call_interpolation.rb
63
- - examples/exec_blank.rb
64
- - examples/exec_interpolation.rb
65
59
  - examples/yaml/array_duration_time.yml
66
60
  - examples/yaml/array_loop.yml
67
- - examples/yaml/array_loop_memory.yml
68
- - examples/yaml/array_loop_time.yml
69
61
  - examples/yaml/blank_hash.yml
70
62
  - examples/yaml/blank_hash_array.yml
71
63
  - examples/yaml/blank_loop.yml
72
- - examples/yaml/blank_loop_time.yml
73
64
  - examples/yaml/blank_string.yml
74
65
  - examples/yaml/blank_string_array.yml
75
66
  - examples/yaml/example_multi.yml
@@ -82,7 +73,6 @@ files:
82
73
  - lib/benchmark/driver/duration_runner.rb
83
74
  - lib/benchmark/driver/error.rb
84
75
  - lib/benchmark/driver/repeatable_runner.rb
85
- - lib/benchmark/driver/ruby_dsl_parser.rb
86
76
  - lib/benchmark/driver/time.rb
87
77
  - lib/benchmark/driver/version.rb
88
78
  - lib/benchmark/driver/yaml_parser.rb
@@ -91,7 +81,6 @@ files:
91
81
  - lib/benchmark/output/memory.rb
92
82
  - lib/benchmark/output/time.rb
93
83
  - lib/benchmark/runner.rb
94
- - lib/benchmark/runner/call.rb
95
84
  - lib/benchmark/runner/exec.rb
96
85
  - lib/benchmark_driver.rb
97
86
  homepage: https://github.com/k0kubun/benchmark_driver
data/examples/call.rb DELETED
@@ -1,12 +0,0 @@
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
@@ -1,13 +0,0 @@
1
- require 'benchmark/driver'
2
-
3
- class Array
4
- alias_method :blank?, :empty?
5
- end
6
-
7
- Benchmark.driver(runner: :call) do |x|
8
- array = []
9
-
10
- x.report('array.empty?') { array.empty? }
11
- x.report('array.blank?') { array.blank? }
12
- x.compare!
13
- end
data/examples/call_erb.rb DELETED
@@ -1,33 +0,0 @@
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>
@@ -1,13 +0,0 @@
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
@@ -1,14 +0,0 @@
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
@@ -1,15 +0,0 @@
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
@@ -1,6 +0,0 @@
1
- output: memory
2
- loop_count: 6000000
3
- benchmark:
4
- array10: a = [1,2,3,4,5,6,7,8,9,10]
5
- array100: a = [1,2,3,4,5,6,7,8,9,10] * 10
6
- array1000: a = [1,2,3,4,5,6,7,8,9,10] * 100
@@ -1,4 +0,0 @@
1
- output: time
2
- loop_count: 6000000
3
- benchmark:
4
- bm_vm2_array: a = [1,2,3,4,5,6,7,8,9,10]
@@ -1,10 +0,0 @@
1
- output: time
2
- loop_count: 20000000
3
- prelude: |
4
- class Array
5
- alias_method :blank?, :empty?
6
- end
7
- array = []
8
- benchmark:
9
- empty: array.empty?
10
- blank: array.blank?
@@ -1,57 +0,0 @@
1
- require 'benchmark/driver/configuration'
2
-
3
- class Benchmark::Driver::RubyDslParser
4
- def initialize(runner: :call, output: :ips)
5
- @prelude = nil
6
- @jobs = []
7
- @runner_options = Benchmark::Driver::Configuration::RunnerOptions.new(runner)
8
- @output_options = Benchmark::Driver::Configuration::OutputOptions.new(output)
9
- end
10
-
11
- # API to fetch configuration parsed from DSL
12
- # @return [Benchmark::Driver::Configuration]
13
- def configuration
14
- @jobs.each do |job|
15
- job.prelude = @prelude
16
- end
17
- Benchmark::Driver::Configuration.new(@jobs).tap do |c|
18
- c.runner_options = @runner_options
19
- c.output_options = @output_options
20
- end
21
- end
22
-
23
- # @param [String] prelude - Script required for benchmark whose execution time is not measured.
24
- def prelude=(prelude)
25
- unless prelude.is_a?(String)
26
- raise ArgumentError.new("prelude must be String but got #{prelude.inspect}")
27
- end
28
- unless @prelude.nil?
29
- raise ArgumentError.new("prelude is already set:\n#{@prelude}")
30
- end
31
-
32
- @prelude = prelude
33
- end
34
-
35
- # @param [String,nil] name - Name shown on result output. This must be provided if block is given.
36
- # @param [String,nil] script - Benchmarked script in String. Only either of script or block must be provided.
37
- # @param [Proc,nil] block - Benchmarked Proc object.
38
- def report(name = nil, script: nil, &block)
39
- if script.nil? && !block_given?
40
- raise ArgumentError.new('script or block must be provided')
41
- elsif !script.nil? && block_given?
42
- raise ArgumentError.new('script and block cannot be specified at the same time')
43
- elsif name.nil? && block_given?
44
- raise ArgumentError.new('name must be specified if block is given')
45
- elsif !name.nil? && !name.is_a?(String)
46
- raise ArgumentError.new("name must be String but got #{name.inspect}")
47
- elsif !script.nil? && !script.is_a?(String)
48
- raise ArgumentError.new("script must be String but got #{script.inspect}")
49
- end
50
-
51
- @jobs << Benchmark::Driver::Configuration::Job.new(name || script, script || block)
52
- end
53
-
54
- def compare!
55
- @output_options.compare = true
56
- end
57
- end
@@ -1,97 +0,0 @@
1
- require 'benchmark/driver/benchmark_result'
2
- require 'benchmark/driver/duration_runner'
3
- require 'benchmark/driver/repeatable_runner'
4
- require 'benchmark/driver/time'
5
-
6
- # Run benchmark by calling #call on running ruby.
7
- #
8
- # Multiple Ruby binaries: x
9
- # Memory output: x
10
- class Benchmark::Runner::Call
11
- # This class can provide fields in `Benchmark::Driver::BenchmarkResult` if required by output plugins.
12
- SUPPORTED_FIELDS = [:real]
13
-
14
- WARMUP_DURATION = 2
15
- BENCHMARK_DURATION = 5
16
-
17
- # @param [Benchmark::Driver::Configuration::RunnerOptions] options
18
- # @param [Benchmark::Output::*] output - Object that responds to methods used in this class
19
- def initialize(options, output:)
20
- @options = options
21
- @output = output
22
- end
23
-
24
- # @param [Benchmark::Driver::Configuration] config
25
- def run(config)
26
- validate_config(config)
27
-
28
- if config.jobs.any?(&:warmup_needed?)
29
- run_warmup(config.jobs)
30
- end
31
-
32
- @output.start_running
33
-
34
- config.jobs.each do |job|
35
- @output.running(job.name)
36
-
37
- result = Benchmark::Driver::RepeatableRunner.new(job).run(
38
- runner: method(:call_times),
39
- repeat_count: @options.repeat_count,
40
- )
41
-
42
- @output.benchmark_stats(result)
43
- end
44
-
45
- @output.finish
46
- end
47
-
48
- private
49
-
50
- def validate_config(config)
51
- if config.runner_options.executables_specified?
52
- raise ArgumentError.new("Benchmark::Runner::Call can't run other Ruby executables")
53
- end
54
-
55
- config.jobs.each do |job|
56
- unless job.script.respond_to?(:call)
57
- raise NotImplementedError.new(
58
- "#{self.class.name} only accepts objects that respond to :call, but got #{job.script.inspect}"
59
- )
60
- end
61
- end
62
- end
63
-
64
- # @param [Array<Benchmark::Driver::Configuration::Job>] jobs
65
- # @return [Hash{ Benchmark::Driver::Configuration::Job => Integer }] iters_by_job
66
- def run_warmup(jobs)
67
- @output.start_warming
68
-
69
- jobs.each do |job|
70
- next if job.loop_count
71
- @output.warming(job.name)
72
-
73
- result = Benchmark::Driver::DurationRunner.new(job).run(
74
- seconds: WARMUP_DURATION,
75
- unit_iters: 1,
76
- runner: method(:call_times),
77
- )
78
- job.guessed_count = (result.ips.to_f * BENCHMARK_DURATION).to_i
79
-
80
- @output.warmup_stats(result)
81
- end
82
- end
83
-
84
- def call_times(job, times)
85
- script = job.script
86
- i = 0
87
-
88
- before = Benchmark::Driver::Time.now
89
- while i < times
90
- script.call
91
- i += 1
92
- end
93
- after = Benchmark::Driver::Time.now
94
-
95
- after.to_f - before.to_f
96
- end
97
- end