benchmark_driver 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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