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 +4 -4
- data/.travis.yml +0 -1
- data/CHANGELOG.md +7 -0
- data/README.md +4 -58
- data/Rakefile +1 -10
- data/examples/yaml/array_duration_time.yml +0 -1
- data/exe/benchmark-driver +49 -31
- data/lib/benchmark/driver.rb +1 -10
- data/lib/benchmark/driver/version.rb +1 -1
- data/lib/benchmark/driver/yaml_parser.rb +2 -50
- data/lib/benchmark/runner.rb +2 -1
- metadata +2 -13
- 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/exec_blank.rb +0 -14
- data/examples/exec_interpolation.rb +0 -15
- data/examples/yaml/array_loop_memory.yml +0 -6
- data/examples/yaml/array_loop_time.yml +0 -4
- data/examples/yaml/blank_loop_time.yml +0 -10
- data/lib/benchmark/driver/ruby_dsl_parser.rb +0 -57
- data/lib/benchmark/runner/call.rb +0 -97
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 47b335872c19aca072e3990d807767428113c3f57fb7b701fd6df4769c94ecf2
         | 
| 4 | 
            +
              data.tar.gz: e1a86a2541e681b2a04db79912da4c079426dd3aa843bc0959edf3321d2fe768
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: e015bc42e98d81dbb6c855159ecee0367fcb2f737b5c0d37dff43bd972c456d97c79c9c00c00034d153fdb1471f3f71cf55ab3a1b0d5e185d1d6d56fdb59ec96
         | 
| 7 | 
            +
              data.tar.gz: bd31b303ef412073906c287b977ac82c4813260239b334824ce419dd3140bfbb76861e3280dee091b41dc1ae2d9fe1cd75cc6234dc5c4e1631c7809a5f27fb3a
         | 
    
        data/.travis.yml
    CHANGED
    
    
    
        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 | 
            -
            -  | 
| 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 | 
            -
             | 
| 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 | 
            -
             | 
| 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:  | 
| 13 | 
            +
            task default: :yaml_examples
         | 
    
        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 | 
            -
             | 
| 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 | 
            -
                 | 
| 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 | 
            -
             | 
| 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 | 
            -
               | 
| 74 | 
            -
             | 
| 75 | 
            -
              end
         | 
| 91 | 
            +
              config.runner_options.executables = options.delete(:execs)
         | 
| 92 | 
            +
            end
         | 
| 76 93 |  | 
| 77 | 
            -
             | 
| 78 | 
            -
             | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 81 | 
            -
             | 
| 82 | 
            -
             | 
| 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)
         | 
    
        data/lib/benchmark/driver.rb
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            module Benchmark
         | 
| 2 2 | 
             
              module Driver
         | 
| 3 3 | 
             
                class << self
         | 
| 4 | 
            -
                  # Main function which is used by  | 
| 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,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 | 
            -
                # @ | 
| 10 | 
            -
                 | 
| 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)
         | 
    
        data/lib/benchmark/runner.rb
    CHANGED
    
    | @@ -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. | 
| 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- | 
| 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
         | 
    
        data/examples/call_blank.rb
    DELETED
    
    
    
        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
         | 
    
        data/examples/exec_blank.rb
    DELETED
    
    | @@ -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,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
         |