benchmark_driver 0.10.0 → 0.10.1

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: 6b444be9753246263a4b3a65f0fe33a07c62f4a538008245fb8a17b2e809f7b6
4
- data.tar.gz: e4a43fb02781c343e266e8c5644d8fc4edf1568de93d620e90500f027bb4418a
3
+ metadata.gz: d2bcdf477d225e851726d6e8296af8b2ace8542c9b3cf3bc0d0d076dc140c8cb
4
+ data.tar.gz: 0d13f33d1fe60a936601377686a3121eee98972d587ad2a13e1828fa5a6a6588
5
5
  SHA512:
6
- metadata.gz: 4c512a0e7bb65debbb79b2f312db9852db1625cfd3a46cab847b81f0d3f85d09caef043e09b1f47679f6b476ea98d2a913ea7fbd1a694aac4621a2e701256450
7
- data.tar.gz: 5fd294728cf04e4524a62aa12916ba4c66b6e9f8dab498cb290a20d324a3aa60b5f53786d6bb150ec1a44d730770a40d77ab8e3f29fcd5c109ed85f5e02c074c
6
+ metadata.gz: bca45d1c0fd8608aa223aa02ce0e1873f6e9bd2a04edb9efebab5dddff0f68be77be3a318613fda3af152e197e3298d97959e7720daa3b2b4ea5e6fffc8ac7b3
7
+ data.tar.gz: '0908488a1465b40d808dfa9f3ead01d1b0647106ed8f88328e3aa1dd3a43d13ad90946f40b81094ba5327b6ff480d7f19060c814749bbe63731cbb0871170437'
data/.travis.yml CHANGED
@@ -1,6 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.10
4
3
  - 2.2.8
5
4
  - 2.3.6
6
5
  - 2.4.3
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # v0.10.1
2
+
3
+ - Add "command\_stdout" runner to plug in existing benchmark
4
+ - Explicitly bump supported Ruby version to >= 2.2
5
+ - v0.10.0 actually does not work with 2.1
6
+ - You can still benchmark Ruby 2.0, 2.1 by --executable, but you need to use newer Ruby for driver
7
+
1
8
  # v0.10.0
2
9
 
3
10
  - Add "record" output and "recorded" runner
@@ -24,6 +31,7 @@
24
31
  - So Ruby interface can't take Proc
25
32
  - YAML can have arbitrary format depending on the runner
26
33
  - `--compare` option is dropped and changed to `--output compare`
34
+ - `--dir` option is dropped for now
27
35
 
28
36
  # v0.8.6
29
37
 
data/README.md CHANGED
@@ -4,7 +4,9 @@ Fully-featured accurate benchmark driver for Ruby
4
4
 
5
5
  ## Project Status
6
6
 
7
- **Under Construction**
7
+ Beta.
8
+
9
+ Interface might be changed in the future, but it's almost fixed and many features can run well.
8
10
 
9
11
  ## Features
10
12
  ### Accurate Measurement
data/Rakefile CHANGED
@@ -12,7 +12,9 @@ task :test do
12
12
  }.each do |runner, output|
13
13
  Bundler.with_clean_env do
14
14
  sh ['time', 'bundle', 'exec', 'exe/benchmark-driver', blank_loop, '-r', runner, '-o', output].shelljoin
15
+ puts
15
16
  sh ['time', 'bundle', 'exec', 'exe/benchmark-driver', blank_hash, '-r', runner, '-o', output, '--run-duration', '1'].shelljoin
17
+ puts
16
18
  end
17
19
  end
18
20
  end
@@ -20,9 +22,13 @@ end
20
22
  task :test_record do
21
23
  blank_loop = File.expand_path('./examples/yaml/blank_loop.yml', __dir__) # no warmup
22
24
  sh ['time', 'bundle', 'exec', 'exe/benchmark-driver', blank_loop, '-r', 'ips', '-o', 'record'].shelljoin
25
+ puts
23
26
  sh ['time', 'bundle', 'exec', 'exe/benchmark-driver', 'benchmark_driver.record.yml', '-o', 'compare'].shelljoin
27
+ puts
24
28
  sh ['time', 'bundle', 'exec', 'exe/benchmark-driver', 'benchmark_driver.record.yml', '-o', 'record'].shelljoin
29
+ puts
25
30
  sh ['time', 'bundle', 'exec', 'exe/benchmark-driver', 'benchmark_driver.record.yml', '-o', 'simple'].shelljoin
31
+ puts
26
32
  end
27
33
 
28
34
  task :test_ruby do
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.bindir = 'exe'
20
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ['lib']
22
- spec.required_ruby_version = '>= 2.1.0'
22
+ spec.required_ruby_version = '>= 2.2.0'
23
23
 
24
24
  spec.add_development_dependency 'bundler'
25
25
  spec.add_development_dependency 'rake'
data/exe/benchmark-driver CHANGED
@@ -5,7 +5,6 @@ require 'benchmark_driver'
5
5
  require 'optparse'
6
6
  require 'yaml'
7
7
 
8
-
9
8
  # Parse command line options
10
9
  config = BenchmarkDriver::Config.new.tap do |c|
11
10
  executables = []
@@ -34,7 +33,7 @@ config = BenchmarkDriver::Config.new.tap do |c|
34
33
  r.split(';').each do |spec|
35
34
  version, *args = spec.split(',')
36
35
  executables << BenchmarkDriver::Config::Executable.new(
37
- name: version,
36
+ name: spec,
38
37
  command: [BenchmarkDriver::Rbenv.ruby_path(version), *args],
39
38
  )
40
39
  end
@@ -55,7 +55,7 @@ class BenchmarkDriver::Output::Compare
55
55
  block.call
56
56
  ensure
57
57
  $stdout.print(@metrics_type.unit)
58
- if job.loop_count
58
+ if job.respond_to?(:loop_count) && job.loop_count
59
59
  $stdout.print(" - #{humanize(job.loop_count)} times")
60
60
  if @job_metrics.all? { |metrics| metrics.duration }
61
61
  $stdout.print(" in")
@@ -1,5 +1,6 @@
1
1
  module BenchmarkDriver
2
2
  module Runner
3
+ require 'benchmark_driver/runner/command_stdout'
3
4
  require 'benchmark_driver/runner/ips'
4
5
  require 'benchmark_driver/runner/memory'
5
6
  require 'benchmark_driver/runner/once'
@@ -0,0 +1,121 @@
1
+ require 'benchmark_driver/struct'
2
+ require 'benchmark_driver/metrics'
3
+ require 'tempfile'
4
+ require 'shellwords'
5
+
6
+ # Run only once, for testing
7
+ class BenchmarkDriver::Runner::CommandStdout
8
+ # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job"
9
+ Job = ::BenchmarkDriver::Struct.new(
10
+ :name, # @param [String] name - This is mandatory for all runner
11
+ :command, # @param [Array<String>]
12
+ :working_directory, # @param [String,NilClass]
13
+ :metrics_type, # @param [BenchmarkDriver::Metrics::Type]
14
+ :stdout_to_metrics, # @param [String]
15
+ )
16
+ # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse`
17
+ class << JobParser = Module.new
18
+ # @param [String] name
19
+ # @param [String] command
20
+ # @param [String,NilClass] working_directory
21
+ # @param [Hash] metrics_type
22
+ # @param [String] stdout_to_metrics
23
+ def parse(name:, command:, working_directory:, metrics_type:, stdout_to_metrics:)
24
+ Job.new(
25
+ name: name,
26
+ command: command.shellsplit,
27
+ working_directory: working_directory,
28
+ metrics_type: parse_metrics_type(metrics_type),
29
+ stdout_to_metrics: stdout_to_metrics,
30
+ )
31
+ end
32
+
33
+ private
34
+
35
+ def parse_metrics_type(unit:, larger_better: nil, worse_word: nil)
36
+ BenchmarkDriver::Metrics::Type.new(
37
+ unit: unit,
38
+ larger_better: larger_better,
39
+ worse_word: worse_word,
40
+ )
41
+ end
42
+ end
43
+
44
+ # @param [BenchmarkDriver::Config::RunnerConfig] config
45
+ # @param [BenchmarkDriver::Output::*] output
46
+ def initialize(config:, output:)
47
+ @config = config
48
+ @output = output
49
+ end
50
+
51
+ # This method is dynamically called by `BenchmarkDriver::JobRunner.run`
52
+ # @param [Array<BenchmarkDriver::Default::Job>] jobs
53
+ def run(jobs)
54
+ metrics_type = jobs.first.metrics_type
55
+ @output.metrics_type = metrics_type
56
+
57
+ @output.with_benchmark do
58
+ jobs.each do |job|
59
+ @output.with_job(job) do
60
+ @config.executables.each do |exec|
61
+ best_value = with_repeat(metrics_type) do
62
+ stdout = with_chdir(job.working_directory) do
63
+ execute(*exec.command, *job.command)
64
+ end
65
+ StdoutToMetrics.new(
66
+ stdout: stdout,
67
+ stdout_to_metrics: job.stdout_to_metrics,
68
+ ).metrics_value
69
+ end
70
+
71
+ @output.report(
72
+ BenchmarkDriver::Metrics.new(
73
+ value: best_value,
74
+ executable: exec,
75
+ )
76
+ )
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ private
84
+
85
+ def with_chdir(working_directory, &block)
86
+ if working_directory
87
+ Dir.chdir(working_directory) { block.call }
88
+ else
89
+ block.call
90
+ end
91
+ end
92
+
93
+ def execute(*args)
94
+ stdout = IO.popen(args, &:read)
95
+ unless $?.success?
96
+ raise "Failed to execute: #{args.shelljoin} (status: #{$?.exitstatus})"
97
+ end
98
+ stdout
99
+ end
100
+
101
+ # Return multiple times and return the best metrics
102
+ def with_repeat(metrics_type, &block)
103
+ values = @config.repeat_count.times.map do
104
+ block.call
105
+ end
106
+ values.sort_by do |value|
107
+ if metrics_type.larger_better
108
+ value
109
+ else
110
+ -value
111
+ end
112
+ end.last
113
+ end
114
+
115
+ StdoutToMetrics = ::BenchmarkDriver::Struct.new(:stdout, :stdout_to_metrics) do
116
+ def metrics_value
117
+ eval(stdout_to_metrics, binding)
118
+ end
119
+ end
120
+ private_constant :StdoutToMetrics
121
+ end
@@ -1,3 +1,3 @@
1
1
  module BenchmarkDriver
2
- VERSION = '0.10.0'
2
+ VERSION = '0.10.1'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: benchmark_driver
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Takashi Kokubun
@@ -82,6 +82,7 @@ files:
82
82
  - lib/benchmark_driver/rbenv.rb
83
83
  - lib/benchmark_driver/ruby_interface.rb
84
84
  - lib/benchmark_driver/runner.rb
85
+ - lib/benchmark_driver/runner/command_stdout.rb
85
86
  - lib/benchmark_driver/runner/ips.rb
86
87
  - lib/benchmark_driver/runner/memory.rb
87
88
  - lib/benchmark_driver/runner/once.rb
@@ -101,7 +102,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
101
102
  requirements:
102
103
  - - ">="
103
104
  - !ruby/object:Gem::Version
104
- version: 2.1.0
105
+ version: 2.2.0
105
106
  required_rubygems_version: !ruby/object:Gem::Requirement
106
107
  requirements:
107
108
  - - ">="