benchkit 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: de0a1955c6cac87008f7aa70b13796dd35b47431
4
+ data.tar.gz: 0b04577f70fd7835cdb0b7930d6cf9a9259bf771
5
+ SHA512:
6
+ metadata.gz: a17a1b3fb5ab065164d17e2a95ad1f001912cf61ccddf6109ddd7ae0917af62dd390e8cb4713a2f3216a767a044a21c6f78f4ff66d2ab5a4af506a2b92c70375
7
+ data.tar.gz: 2e59277b92fa9bf5689445aef98783da640a754959a57a360b964b1dae174b517097aeb0cfe302b77bcef0a2c15fc0cde14431df5e967b58ed5c411bb800df53
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.1
5
+ before_install: gem install bundler -v 1.15.4
6
+ script:
7
+ - bundle exec rake
8
+
9
+ # Test some options
10
+ - bundle exec exe/benchmark_driver ruby_benchmark_set/example_single.yml -e ruby1::ruby -e ruby2::ruby -i
11
+ - bundle exec exe/benchmark_driver ruby_benchmark_set/example_single.yml -e ruby1::ruby -e ruby2::ruby -i 2
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in benchmark_driver.gemspec
6
+ gemspec
7
+
8
+ gem 'pry'
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Takashi Kokubun
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,171 @@
1
+ # Benchkit [![Build Status](https://travis-ci.org/k0kubun/benchmark_driver.svg?branch=master)](https://travis-ci.org/k0kubun/benchmark_driver)
2
+
3
+ Benchmark driver for different Ruby executables
4
+
5
+ ## Installation
6
+
7
+ $ gem install benchmark_driver
8
+
9
+ ## Usage
10
+
11
+ ```
12
+ $ exe/benchmark_driver -h
13
+ Usage: benchmark_driver [options] [YAML]
14
+ -e, --executables [EXECS] Ruby executables (e1::path1; e2::path2; e3::path3;...)
15
+ -i, --ips [SECONDS] Measure IPS in duration seconds (default: 1)
16
+ -l, --loop-count [COUNT] Measure execution time with loop count (default: 100000)
17
+ -v, --verbose
18
+ ```
19
+
20
+ ### Running single script
21
+
22
+ With following `example_single.yml`,
23
+
24
+ ```yml
25
+ prelude: |
26
+ require 'erb'
27
+ erb = ERB.new(%q[Hello <%= 'World' %>])
28
+ benchmark: erb.result
29
+ ```
30
+
31
+ you can benchmark the script with multiple ruby executables.
32
+
33
+ ```
34
+ $ exe/benchmark_driver ruby_benchmark_set/example_single.yml -e ruby1::ruby -e ruby2::ruby
35
+ benchmark results:
36
+ Execution time (sec)
37
+ name ruby1 ruby2
38
+ example_single 0.958 0.972
39
+
40
+ Speedup ratio: compare with the result of `ruby1' (greater is better)
41
+ name ruby2
42
+ example_single 0.986
43
+ ```
44
+
45
+ And you can change benchmark output to IPS (iteration per second) by `-i` option.
46
+
47
+ ```
48
+ $ exe/benchmark_driver ruby_benchmark_set/example_single.yml -e ruby1::ruby -e ruby2::ruby -i
49
+ Result -------------------------------------------
50
+ ruby1 ruby2
51
+ example_single 99414.1 i/s 99723.3 i/s
52
+
53
+ Comparison: example_single
54
+ ruby2: 99723.3 i/s
55
+ ruby1: 99414.1 i/s - 1.00x slower
56
+ ```
57
+
58
+ ### Running multiple scripts
59
+
60
+ One YAML file can contain multiple benchmark scripts.
61
+ With following `example_multi.yml`,
62
+
63
+ ```yml
64
+ prelude: |
65
+ a = 'a' * 100
66
+ b = 'b' * 100
67
+ benchmarks:
68
+ - name: join
69
+ benchmark: |
70
+ [a, b].join
71
+ - name: interpolation
72
+ benchmark: |
73
+ "#{a}#{b}"
74
+ ```
75
+
76
+ you can benchmark the scripts with multiple ruby executables.
77
+
78
+ ```
79
+ $ exe/benchmark_driver ruby_benchmark_set/example_multi.yml -e ruby1::ruby -e ruby2::ruby
80
+ benchmark results:
81
+ Execution time (sec)
82
+ name ruby1 ruby2
83
+ join 0.022 0.022
84
+ interpolation 0.026 0.026
85
+
86
+ Speedup ratio: compare with the result of `ruby1' (greater is better)
87
+ name ruby2
88
+ join 1.045
89
+ interpolation 1.002
90
+ ```
91
+
92
+ ```
93
+ $ exe/benchmark_driver ruby_benchmark_set/example_multi.yml -e ruby1::ruby -e ruby2::ruby -i
94
+ Result -------------------------------------------
95
+ ruby1 ruby2
96
+ join 4701954.3 i/s 4639520.3 i/s
97
+ interpolation 4263170.0 i/s 4044083.0 i/s
98
+
99
+ Comparison: join
100
+ ruby1: 4701954.3 i/s
101
+ ruby2: 4639520.3 i/s - 1.01x slower
102
+
103
+ Comparison: interpolation
104
+ ruby1: 4263170.0 i/s
105
+ ruby2: 4044083.0 i/s - 1.05x slower
106
+ ```
107
+
108
+ ### Configuring modes
109
+
110
+ There are 2 modes:
111
+
112
+ - Loop count: Enabled by `-l`. Optionally you can change count to loop by `-l COUNT`.
113
+ - IPS: Enabled by `-i`. Optionally you can change duration by `-i DURATION`.
114
+
115
+ Specifying both `-l` and `-i` is nonsense.
116
+
117
+ ### YAML syntax
118
+ You can specify `benchmark:` or `benchmarks:`.
119
+
120
+ #### Single
121
+ ```yml
122
+ name: String # optional (default: file name)
123
+ prelude: String # optional
124
+ loop_count: Integer # optional
125
+ benchmark: String # required
126
+ ```
127
+
128
+ #### Multi
129
+
130
+ ```yml
131
+ prelude: String # optional (shared)
132
+ loop_count: Integer # optional (shared)
133
+ benchmarks:
134
+ - name: String # required
135
+ prelude: String # optional (benchmark specific)
136
+ loop_count: Integer # optional (benchmark specific)
137
+ benchmark: String # required
138
+ ```
139
+
140
+ ### Debugging
141
+
142
+ If you have a trouble like an unexpectedly fast result, you should check benchmark script by `-v`.
143
+
144
+ ```
145
+ $ exe/benchmark_driver ruby_benchmark_set/example_multi.yml -v
146
+ --- Running "join" with "ruby" 957780 times ---
147
+ a = 'a' * 100
148
+ b = 'b' * 100
149
+
150
+
151
+ i = 0
152
+ while i < 957780
153
+ i += 1
154
+ [a, b].join
155
+
156
+ end
157
+ ```
158
+
159
+ ## TODO
160
+
161
+ - Measure multiple times and use minimum result
162
+ - Retry and reject negative result in ips mode
163
+ - Change not to take long time for iteration count estimation in ips mode
164
+
165
+ ## Contributing
166
+
167
+ Bug reports and pull requests are welcome on GitHub at https://github.com/k0kubun/benchmark_driver.
168
+
169
+ ## License
170
+
171
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ desc 'Run benchmarks in ruby_benchmark_set'
4
+ task :ruby_benchmark_set do
5
+ require 'bundler'
6
+ require 'shellwords'
7
+
8
+ Dir.glob(File.expand_path('./ruby_benchmark_set/**/*.yml', __dir__)).sort.each do |path|
9
+ Bundler.with_clean_env do
10
+ sh [File.expand_path('./exe/benchmark_driver', __dir__), path].shelljoin
11
+ end
12
+ end
13
+ end
14
+
15
+ task default: :ruby_benchmark_set
data/benchkit.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'benchkit/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'benchkit'
8
+ spec.version = Benchkit::VERSION
9
+ spec.authors = ['Takashi Kokubun']
10
+ spec.email = ['takashikkbn@gmail.com']
11
+
12
+ spec.summary = %q{Benchmark driver}
13
+ spec.description = %q{Benchmark driver}
14
+ spec.homepage = 'https://github.com/k0kubun/benchmark_driver'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = 'exe'
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ['lib']
23
+ spec.required_ruby_version = '>= 2.3.0'
24
+
25
+ spec.add_development_dependency 'bundler'
26
+ spec.add_development_dependency 'rake'
27
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "benchmark_driver"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/exe/benchkit ADDED
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path('../lib', __dir__)
3
+
4
+ require 'benchkit'
5
+ require 'optparse'
6
+ require 'yaml'
7
+
8
+ options = {}
9
+ args = OptionParser.new do |o|
10
+ o.banner = "Usage: #{File.basename($0, '.*')} [options] [YAML]"
11
+ o.on('-e', '--executables [EXECS]', 'Ruby executables (e1::path1; e2::path2; e3::path3;...)') do |e|
12
+ options[:execs] ||= []
13
+ e.split(/;/).each do |path|
14
+ options[:execs] << path
15
+ end
16
+ end
17
+ o.on('-i [DURATION]', '--ips [SECONDS]', "Measure IPS in duration seconds (default: #{Benchkit::DEFAULT_IPS_DURATION})") do |i|
18
+ options[:measure_type] = 'ips'
19
+ options[:measure_num] = Integer(i) if i
20
+ end
21
+ o.on('-l [COUNT]', '--loop-count [COUNT]', "Measure execution time with loop count (default: #{Benchkit::DEFAULT_LOOP_COUNT})") do |l|
22
+ options[:measure_type] = 'loop_count'
23
+ options[:measure_num] = l if l
24
+ end
25
+ o.on('-v', '--verbose') do |v|
26
+ options[:verbose] = v
27
+ end
28
+ end.parse!(ARGV)
29
+ abort "No YAML file is specified" if args.empty?
30
+
31
+ driver = Benchkit.new(options)
32
+ args.each do |yaml|
33
+ default = { name: File.basename(yaml, '.*') }
34
+ driver.run(default.merge(YAML.load(File.read(yaml))))
35
+ end
@@ -0,0 +1,3 @@
1
+ class Benchkit
2
+ VERSION = '0.2.0'
3
+ end
data/lib/benchkit.rb ADDED
@@ -0,0 +1,273 @@
1
+ require 'benchkit/version'
2
+ require 'benchmark'
3
+ require 'tempfile'
4
+
5
+ class Benchkit
6
+ MEASURE_TYPES = %w[loop_count ips]
7
+ DEFAULT_LOOP_COUNT = 100_000
8
+ DEFAULT_IPS_DURATION = 1
9
+
10
+ # @param [String] measure_type - "loop_count"|"ips"
11
+ # @param [Integer,nil] measure_num - Loop count for "loop_type", duration seconds for "ips"
12
+ # @param [Array<String>] execs - ["path1", "path2"] or `["ruby1::path1", "ruby2::path2"]`
13
+ # @param [Boolean] verbose
14
+ def initialize(measure_type: 'loop_count', measure_num: nil, execs: ['ruby'], verbose: false)
15
+ unless MEASURE_TYPES.include?(measure_type)
16
+ abort "unsupported measure type: #{measure_type.dump}"
17
+ end
18
+ @measure_type = measure_type
19
+ @measure_num = measure_num
20
+ @execs = execs.map do |exec|
21
+ name, path = exec.split('::', 2)
22
+ Executable.new(name, path || name)
23
+ end
24
+ @verbose = verbose
25
+ end
26
+
27
+ # @param [Hash] root_hash
28
+ def run(root_hash)
29
+ root = BenchmarkRoot.new(Hash[root_hash.map { |k, v| [k.to_sym, v] }])
30
+
31
+ results = root.benchmarks.map do |benchmark|
32
+ metrics_by_exec = {}
33
+ iterations = calc_iterations(@execs.first, benchmark)
34
+ @execs.each do |exec|
35
+ if @verbose
36
+ puts "--- Running #{benchmark.name.dump} with #{exec.name.dump} #{iterations} times ---"
37
+ puts "#{benchmark.benchmark_script(iterations)}\n"
38
+ end
39
+ elapsed_time = run_benchmark(exec, benchmark, iterations)
40
+ metrics_by_exec[exec] = BenchmarkMetrics.new(iterations, elapsed_time)
41
+ end
42
+ BenchmarkResult.new(benchmark.name, metrics_by_exec)
43
+ end
44
+ puts if @verbose
45
+
46
+ case @measure_type
47
+ when 'loop_count'
48
+ LoopCountReporter.report(@execs, results)
49
+ when 'ips'
50
+ IpsReporter.report(@execs, results)
51
+ else
52
+ raise "unexpected measure type: #{@measure_type.dump}"
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ # Estimate iterations to finish benchmark within `@duration`.
59
+ def calc_iterations(exec, benchmark)
60
+ case @measure_type
61
+ when 'loop_count'
62
+ @measure_num || benchmark.loop_count || DEFAULT_LOOP_COUNT
63
+ when 'ips'
64
+ # TODO: Change to try from 1, 10, 100 ...
65
+ base = 1000
66
+ time = run_benchmark(exec, benchmark, base)
67
+ duration = @measure_num || DEFAULT_IPS_DURATION
68
+ (duration / time * base).to_i
69
+ else
70
+ raise "unexpected measure type: #{@measure_type.dump}"
71
+ end
72
+ end
73
+
74
+ def run_benchmark(exec, benchmark, iterations)
75
+ # TODO: raise error if negative
76
+ measure_script(exec.path, benchmark.benchmark_script(iterations)) -
77
+ measure_script(exec.path, benchmark.overhead_script(iterations))
78
+ end
79
+
80
+ def measure_script(ruby, script)
81
+ Tempfile.create(File.basename(__FILE__)) do |f|
82
+ f.write(script)
83
+ f.close
84
+
85
+ cmd = "#{ruby} #{f.path}"
86
+ Benchmark.measure { system(cmd, out: File::NULL) }.real
87
+ end
88
+ end
89
+
90
+ class BenchmarkRoot
91
+ # @param [String] name
92
+ # @param [String] prelude
93
+ # @param [Integer,nil] loop_count
94
+ # @param [String,nil] benchmark - For running single instant benchmark
95
+ # @param [Array<Hash>] benchmarks - For running multiple benchmarks
96
+ def initialize(name:, prelude: '', loop_count: nil, benchmark: nil, benchmarks: [])
97
+ if benchmark
98
+ unless benchmarks.empty?
99
+ raise ArgumentError.new("Only either :benchmark or :benchmarks can be specified")
100
+ end
101
+ @benchmarks = [BenchmarkScript.new(name: name, prelude: prelude, benchmark: benchmark)]
102
+ else
103
+ @benchmarks = benchmarks.map do |hash|
104
+ BenchmarkScript.new(Hash[hash.map { |k, v| [k.to_sym, v] }]).tap do |b|
105
+ b.inherit_root(prelude: prelude, loop_count: loop_count)
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ # @return [Array<BenchmarkScript>]
112
+ attr_reader :benchmarks
113
+ end
114
+
115
+ class BenchmarkScript
116
+ # @param [String] name
117
+ # @param [String] prelude
118
+ # @param [String] benchmark
119
+ def initialize(name:, prelude: '', loop_count: nil, benchmark:)
120
+ @name = name
121
+ @prelude = prelude
122
+ @loop_count = loop_count
123
+ @benchmark = benchmark
124
+ end
125
+
126
+ # @return [String]
127
+ attr_reader :name
128
+
129
+ # @return [Integer]
130
+ attr_reader :loop_count
131
+
132
+ def inherit_root(prelude:, loop_count:)
133
+ @prelude = "#{prelude}\n#{@prelude}"
134
+ if @loop_count.nil? && loop_count
135
+ @loop_count = loop_count
136
+ end
137
+ end
138
+
139
+ def overhead_script(iterations)
140
+ <<-RUBY
141
+ #{@prelude}
142
+ i = 0
143
+ while i < #{iterations}
144
+ i += 1
145
+ end
146
+ RUBY
147
+ end
148
+
149
+ def benchmark_script(iterations)
150
+ <<-RUBY
151
+ #{@prelude}
152
+ i = 0
153
+ while i < #{iterations}
154
+ i += 1
155
+ #{@benchmark}
156
+ end
157
+ RUBY
158
+ end
159
+ end
160
+
161
+ class BenchmarkResult < Struct.new(
162
+ :name, # @param [String]
163
+ :metrics_by_exec, # @param [Hash{ Executable => BenchmarkMetrics }]
164
+ )
165
+ def iterations_of(exec)
166
+ metrics_by_exec.fetch(exec).iterations
167
+ end
168
+
169
+ def elapsed_time_of(exec)
170
+ metrics_by_exec.fetch(exec).elapsed_time
171
+ end
172
+
173
+ def ips_of(exec)
174
+ iterations_of(exec) / elapsed_time_of(exec)
175
+ end
176
+ end
177
+
178
+ class BenchmarkMetrics < Struct.new(
179
+ :iterations, # @param [Integer]
180
+ :elapsed_time, # @param [Float] - Elapsed time in seconds
181
+ )
182
+ end
183
+
184
+ class Executable < Struct.new(
185
+ :name, # @param [String]
186
+ :path, # @param [String]
187
+ )
188
+ end
189
+
190
+ module LoopCountReporter
191
+ class << self
192
+ # @param [Array<Executable>] execs
193
+ # @param [Array<BenchmarkResult>] results
194
+ def report(execs, results)
195
+ puts "benchmark results:"
196
+ puts "Execution time (sec)"
197
+ puts "#{'%-16s' % 'name'} #{execs.map { |e| "%-8s" % e.name }.join(' ')}"
198
+
199
+ results.each do |result|
200
+ print '%-16s ' % result.name
201
+ puts execs.map { |exec|
202
+ "%-8s" % ("%.3f" % result.elapsed_time_of(exec))
203
+ }.join(' ')
204
+ end
205
+ puts
206
+
207
+ if execs.size > 1
208
+ report_speedup(execs, results)
209
+ end
210
+ end
211
+
212
+ private
213
+
214
+ def report_speedup(execs, results)
215
+ compared = execs.first
216
+ rest = execs - [compared]
217
+
218
+ puts "Speedup ratio: compare with the result of `#{compared.name}' (greater is better)"
219
+ puts "#{'%-16s' % 'name'} #{rest.map { |e| "%-8s" % e.name }.join(' ')}"
220
+ results.each do |result|
221
+ print '%-16s ' % result.name
222
+ puts rest.map { |exec|
223
+ "%-8s" % ("%.3f" % (result.ips_of(exec) / result.ips_of(compared)))
224
+ }.join(' ')
225
+ end
226
+ puts
227
+ end
228
+ end
229
+ end
230
+
231
+ module IpsReporter
232
+ class << self
233
+ # @param [Array<Executable>] execs
234
+ # @param [Array<BenchmarkResult>] results
235
+ def report(execs, results)
236
+ puts "Result -------------------------------------------"
237
+ puts "#{' ' * 16} #{execs.map { |e| "%13s" % e.name }.join(' ')}"
238
+
239
+ results.each do |result|
240
+ print '%16s ' % result.name
241
+ puts execs.map { |exec|
242
+ "%13s" % ("%.1f i/s" % result.ips_of(exec))
243
+ }.join(' ')
244
+ end
245
+ puts
246
+
247
+ if execs.size > 1
248
+ compare(execs, results)
249
+ end
250
+ end
251
+
252
+ private
253
+
254
+ def compare(execs, results)
255
+ results.each do |result|
256
+ puts "Comparison: #{result.name}"
257
+
258
+ sorted = execs.sort_by { |e| -result.ips_of(e) }
259
+ first = sorted.first
260
+
261
+ sorted.each do |exec|
262
+ if exec == first
263
+ puts "%16s: %12s i/s" % [first.name, "%.1f" % result.ips_of(first)]
264
+ else
265
+ puts "%16s: %12s i/s - %.2fx slower" % [exec.name, "%.1f" % result.ips_of(exec), result.ips_of(first) / result.ips_of(exec)]
266
+ end
267
+ end
268
+ puts
269
+ end
270
+ end
271
+ end
272
+ end
273
+ end
@@ -0,0 +1,4 @@
1
+ benchmarks:
2
+ - name: bm_vm2_array
3
+ benchmark: a = [1,2,3,4,5,6,7,8,9,10]
4
+ loop_count: 6000000
@@ -0,0 +1,10 @@
1
+ prelude: |
2
+ a = 'a' * 100
3
+ b = 'b' * 100
4
+ benchmarks:
5
+ - name: join
6
+ benchmark: |
7
+ [a, b].join
8
+ - name: interpolation
9
+ benchmark: |
10
+ "#{a}#{b}"
@@ -0,0 +1,4 @@
1
+ prelude: |
2
+ require 'erb'
3
+ erb = ERB.new(%q[Hello <%= 'World' %>])
4
+ benchmark: erb.result
@@ -0,0 +1,30 @@
1
+ prelude: |
2
+ require 'erb'
3
+
4
+ template = <<EOS
5
+ <html>
6
+ <head> <%= title %> </head>
7
+ <body>
8
+ <h1> <%= title %> </h1>
9
+ <p>
10
+ <%= content %>
11
+ </p>
12
+ </body>
13
+ </html>
14
+ EOS
15
+
16
+ title = "hello world!"
17
+ content = "hello world!\n" * 10
18
+
19
+ benchmarks:
20
+ - name: ERB compiling
21
+ benchmark: ERB.new(template)
22
+ loop_count: 10000
23
+
24
+ - name: ERB rendering
25
+ prelude: |
26
+ src = "def self.render(title, content); #{ERB.new(template).src}; end"
27
+ mod = Module.new
28
+ mod.instance_eval(src, "(ERB)")
29
+ benchmark: mod.render(title, content)
30
+ loop_count: 100000
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: benchkit
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Takashi Kokubun
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-10-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Benchmark driver
42
+ email:
43
+ - takashikkbn@gmail.com
44
+ executables:
45
+ - benchkit
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitignore"
50
+ - ".travis.yml"
51
+ - Gemfile
52
+ - LICENSE.txt
53
+ - README.md
54
+ - Rakefile
55
+ - benchkit.gemspec
56
+ - bin/console
57
+ - bin/setup
58
+ - exe/benchkit
59
+ - lib/benchkit.rb
60
+ - lib/benchkit/version.rb
61
+ - ruby_benchmark_set/core/array.yml
62
+ - ruby_benchmark_set/example_multi.yml
63
+ - ruby_benchmark_set/example_single.yml
64
+ - ruby_benchmark_set/lib/erb.yml
65
+ homepage: https://github.com/k0kubun/benchmark_driver
66
+ licenses:
67
+ - MIT
68
+ metadata: {}
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: 2.3.0
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 2.6.13
86
+ signing_key:
87
+ specification_version: 4
88
+ summary: Benchmark driver
89
+ test_files: []