benchmark-inputs 1.1.0 → 1.1.1
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 +7 -3
- data/CHANGELOG.md +5 -0
- data/Gemfile +4 -1
- data/README.md +35 -25
- data/Rakefile +0 -13
- data/benchmark-inputs.gemspec +12 -11
- data/lib/benchmark/inputs.rb +35 -59
- data/lib/benchmark/inputs/version.rb +1 -1
- metadata +10 -63
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ace507d5a3b56178d74bafca22757751db45fc0aa35fcf11688fcfd0ab6a5359
|
4
|
+
data.tar.gz: e25a1f06aa67210490fb418dd96a00deb3014cd6b1d72f291afda0ff62b271b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 489255b3e502c218342f416b98d1c3ab3281088dafb62156fa2782529619a1d35b8cd13a38c7075e816a9869ce6bc39dec505c46eec5f2958c2c0351eeb494a1
|
7
|
+
data.tar.gz: f7fa7a6f0107022bb1e1b56830eb414d0dfb60a95f1986d7629ebfaae4dc6d8f376b12e7aace21f117034f461e1169be235fe876c902e29fc4e5111f5ccfaa0d
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# benchmark-inputs
|
1
|
+
# benchmark-inputs [](https://travis-ci.org/jonathanhefner/benchmark-inputs)
|
2
2
|
|
3
3
|
Input-focused benchmarking for Ruby. Given one or more blocks and an
|
4
4
|
array of inputs to yield to each of them, benchmark-inputs will measure
|
@@ -18,8 +18,8 @@ require "benchmark/ips" ### USING benchmark-ips (NOT benchmark-inputs)
|
|
18
18
|
|
19
19
|
STRINGS = ["abc", "aaa", "xyz", ""]
|
20
20
|
Benchmark.ips do |job|
|
21
|
-
job.report("String#tr"){ STRINGS.each{|
|
22
|
-
job.report("String#gsub"){ STRINGS.each{|
|
21
|
+
job.report("String#tr"){ STRINGS.each{|string| string.tr("a", "A") } }
|
22
|
+
job.report("String#gsub"){ STRINGS.each{|string| string.gsub(/a/, "A") } }
|
23
23
|
job.compare!
|
24
24
|
end
|
25
25
|
```
|
@@ -33,33 +33,36 @@ each value individually, but that is more verbose and more error-prone:
|
|
33
33
|
```ruby
|
34
34
|
require "benchmark/ips" ### USING benchmark-ips (NOT benchmark-inputs)
|
35
35
|
|
36
|
-
|
36
|
+
string1, string2, string3, string4 = ["abc", "aaa", "xyz", ""]
|
37
37
|
Benchmark.ips do |job|
|
38
38
|
job.report("String#tr") do
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
string1.tr("a", "A")
|
40
|
+
string2.tr("a", "A")
|
41
|
+
string3.tr("a", "A")
|
42
|
+
string4.tr("a", "A")
|
43
43
|
end
|
44
44
|
job.report("String#gsub") do
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
string1.gsub(/a/, "A")
|
46
|
+
string2.gsub(/a/, "A")
|
47
|
+
string3.gsub(/a/, "A")
|
48
|
+
string4.gsub(/a/, "A")
|
49
49
|
end
|
50
50
|
job.compare!
|
51
51
|
end
|
52
52
|
```
|
53
53
|
|
54
|
+
|
55
|
+
## Usage
|
56
|
+
|
54
57
|
*Enter benchmark-inputs*. Here is how the same benchmark looks using
|
55
|
-
this gem:
|
58
|
+
this gem:
|
56
59
|
|
57
60
|
```ruby
|
58
61
|
require "benchmark/inputs" ### USING benchmark-inputs
|
59
62
|
|
60
63
|
Benchmark.inputs(["abc", "aaa", "xyz", ""]) do |job|
|
61
|
-
job.report("String#tr"){|
|
62
|
-
job.report("String#gsub"){|
|
64
|
+
job.report("String#tr"){|string| string.tr("a", "A") }
|
65
|
+
job.report("String#gsub"){|string| string.gsub(/a/, "A") }
|
63
66
|
job.compare!
|
64
67
|
end
|
65
68
|
```
|
@@ -93,8 +96,8 @@ behind the scenes. To enable this, use the `dup_inputs` option:
|
|
93
96
|
require "benchmark/inputs"
|
94
97
|
|
95
98
|
Benchmark.inputs(["abc", "aaa", "xyz", ""], dup_inputs: true) do |job|
|
96
|
-
job.report("String#tr!"){|
|
97
|
-
job.report("String#gsub!"){|
|
99
|
+
job.report("String#tr!"){|string| string.tr!("a", "A") }
|
100
|
+
job.report("String#gsub!"){|string| string.gsub!(/a/, "A") }
|
98
101
|
job.compare!
|
99
102
|
end
|
100
103
|
```
|
@@ -112,13 +115,18 @@ Comparison:
|
|
112
115
|
String#gsub!: 281588.6 i/s - 6.37x slower
|
113
116
|
```
|
114
117
|
|
115
|
-
|
118
|
+
The above shows a slightly larger performance gap than the previous
|
116
119
|
benchmark. This makes sense because the overhead of allocating new
|
117
120
|
strings -- previously via a non-bang method, but now via `dup` -- is now
|
118
121
|
excluded from the timings. Thus, the speed of `tr!` relative to `gsub!`
|
119
122
|
is further emphasized.
|
120
123
|
|
121
124
|
|
125
|
+
## API
|
126
|
+
|
127
|
+
See the [API documentation](https://www.rubydoc.info/gems/benchmark-inputs).
|
128
|
+
|
129
|
+
|
122
130
|
## Limitations
|
123
131
|
|
124
132
|
`Benchmark.inputs` generates code based on the array of input values it
|
@@ -126,26 +134,28 @@ is given. Each input value becomes a local variable. While there is
|
|
126
134
|
theoretically no limit to the number of local variables that can be
|
127
135
|
generated, more than a few hundred may slow down the benchmark. But,
|
128
136
|
because input values are used to represent different scenarios rather
|
129
|
-
than control the number of invocations, this limitation
|
130
|
-
problem.
|
137
|
+
than control the number of invocations, this limitation should not pose
|
138
|
+
a problem.
|
131
139
|
|
132
140
|
|
133
141
|
## Installation
|
134
142
|
|
143
|
+
Install the [gem](https://rubygems.org/gems/benchmark-inputs):
|
144
|
+
|
135
145
|
```bash
|
136
146
|
$ gem install benchmark-inputs
|
137
147
|
```
|
138
148
|
|
149
|
+
Then require in your benchmark script:
|
139
150
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
[API documentation](http://www.rubydoc.info/gems/benchmark-inputs).
|
151
|
+
```ruby
|
152
|
+
require "benchmark/inputs"
|
153
|
+
```
|
144
154
|
|
145
155
|
|
146
156
|
## License
|
147
157
|
|
148
|
-
[MIT License](
|
158
|
+
[MIT License](LICENSE.txt)
|
149
159
|
|
150
160
|
|
151
161
|
|
data/Rakefile
CHANGED
@@ -1,18 +1,5 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rake/testtask"
|
3
|
-
require "yard"
|
4
|
-
|
5
|
-
|
6
|
-
desc 'Launch IRB with this gem pre-loaded'
|
7
|
-
task :irb do
|
8
|
-
require "benchmark/inputs"
|
9
|
-
require "irb"
|
10
|
-
ARGV.clear
|
11
|
-
IRB.start
|
12
|
-
end
|
13
|
-
|
14
|
-
YARD::Rake::YardocTask.new(:doc) do |t|
|
15
|
-
end
|
16
3
|
|
17
4
|
Rake::TestTask.new(:test) do |t|
|
18
5
|
t.libs << "test"
|
data/benchmark-inputs.gemspec
CHANGED
@@ -1,25 +1,26 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'benchmark/inputs/version'
|
1
|
+
require_relative "lib/benchmark/inputs/version"
|
5
2
|
|
6
3
|
Gem::Specification.new do |spec|
|
7
4
|
spec.name = "benchmark-inputs"
|
8
5
|
spec.version = Benchmark::Inputs::VERSION
|
9
6
|
spec.authors = ["Jonathan Hefner"]
|
10
|
-
spec.email = ["jonathan
|
7
|
+
spec.email = ["jonathan@hefner.pro"]
|
11
8
|
|
12
9
|
spec.summary = %q{Input-focused benchmarking}
|
13
10
|
spec.homepage = "https://github.com/jonathanhefner/benchmark-inputs"
|
14
11
|
spec.license = "MIT"
|
12
|
+
spec.required_ruby_version = ">= 2.2"
|
15
13
|
|
16
|
-
spec.
|
14
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
15
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
16
|
+
spec.metadata["changelog_uri"] = spec.metadata["source_code_uri"] + "/blob/master/CHANGELOG.md"
|
17
|
+
|
18
|
+
# Specify which files should be added to the gem when it is released.
|
19
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
20
|
+
spec.files = Dir.chdir(__dir__) do
|
21
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
22
|
+
end
|
17
23
|
spec.bindir = "exe"
|
18
24
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
25
|
spec.require_paths = ["lib"]
|
20
|
-
|
21
|
-
spec.add_development_dependency "bundler", "~> 1.12"
|
22
|
-
spec.add_development_dependency "rake", ">= 10.0"
|
23
|
-
spec.add_development_dependency "minitest", "~> 5.0"
|
24
|
-
spec.add_development_dependency "yard", "~> 0.9"
|
25
26
|
end
|
data/lib/benchmark/inputs.rb
CHANGED
@@ -2,44 +2,41 @@ require "benchmark/inputs/version"
|
|
2
2
|
|
3
3
|
module Benchmark
|
4
4
|
|
5
|
-
# Initializes a benchmark
|
6
|
-
# job to the given block.
|
5
|
+
# Initializes a benchmark Job, and yields the Job to the given block.
|
7
6
|
#
|
8
7
|
# @example Benchmarking non-destructive operations
|
9
8
|
# Benchmark.inputs(["abc", "aaa", "xyz", ""]) do |job|
|
10
|
-
# job.report("String#tr"){|
|
11
|
-
# job.report("String#gsub"){|
|
9
|
+
# job.report("String#tr"){|string| string.tr("a", "A") }
|
10
|
+
# job.report("String#gsub"){|string| string.gsub(/a/, "A") }
|
12
11
|
# job.compare!
|
13
12
|
# end
|
14
13
|
#
|
15
14
|
# @example Benchmarking destructive operations
|
16
15
|
# Benchmark.inputs(["abc", "aaa", "xyz", ""], dup_inputs: true) do |job|
|
17
|
-
# job.report("String#tr!"){|
|
18
|
-
# job.report("String#gsub!"){|
|
16
|
+
# job.report("String#tr!"){|string| string.tr!("a", "A") }
|
17
|
+
# job.report("String#gsub!"){|string| string.gsub!(/a/, "A") }
|
19
18
|
# job.compare!
|
20
19
|
# end
|
21
20
|
#
|
22
21
|
# @param values [Array]
|
23
|
-
#
|
22
|
+
# Input values to be individually yielded to all {Inputs::Job#report
|
23
|
+
# +report+} blocks
|
24
24
|
# @param options [Hash]
|
25
|
-
# @option options :dup_inputs [Boolean]
|
26
|
-
#
|
27
|
-
# {Inputs::Job#report} block
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
# take when
|
33
|
-
#
|
34
|
-
# configures job and runs benchmarks
|
25
|
+
# @option options :dup_inputs [Boolean] (false)
|
26
|
+
# Whether each of +values+ should be +dup+'d before being yielded to
|
27
|
+
# a {Inputs::Job#report +report+} block. This should be set to true
|
28
|
+
# if any +report+ block destructively modifies its input.
|
29
|
+
# @option options :sample_n [Integer] (10)
|
30
|
+
# Number of samples to take when benchmarking
|
31
|
+
# @option options :sample_dt [Integer] (200,000 ns)
|
32
|
+
# Approximate duration of time each sample should take when
|
33
|
+
# benchmarking, in nanoseconds
|
35
34
|
# @yieldparam job [Benchmark::Inputs::Job]
|
36
|
-
# benchmark runner
|
37
35
|
# @return [Benchmark::Inputs::Job]
|
38
|
-
# benchmark runner
|
39
36
|
# @raise [ArgumentError]
|
40
37
|
# if +values+ is empty
|
41
38
|
def self.inputs(values, **options)
|
42
|
-
job = Inputs::Job.new(values, options)
|
39
|
+
job = Inputs::Job.new(values, **options)
|
43
40
|
yield job
|
44
41
|
job
|
45
42
|
end
|
@@ -47,23 +44,14 @@ module Benchmark
|
|
47
44
|
|
48
45
|
module Inputs
|
49
46
|
|
47
|
+
# @!visibility private
|
50
48
|
NS_PER_S = 1_000_000_000
|
49
|
+
# @!visibility private
|
51
50
|
NS_PER_MS = NS_PER_S / 1_000
|
52
51
|
|
53
52
|
class Job
|
54
53
|
|
55
|
-
#
|
56
|
-
# input values to yield to each benchmark action
|
57
|
-
# @param dup_inputs [Boolean]
|
58
|
-
# whether input values will be +dup+-ed before they are passed
|
59
|
-
# to a {report} block
|
60
|
-
# @param sample_n [Integer]
|
61
|
-
# number of samples to take when benchmarking
|
62
|
-
# @param sample_dt [Integer]
|
63
|
-
# approximate duration of time (in nanoseconds) each sample
|
64
|
-
# should take when benchmarking
|
65
|
-
# @raise [ArgumentError]
|
66
|
-
# if +inputs+ is empty
|
54
|
+
# @!visibility private
|
67
55
|
def initialize(inputs, dup_inputs: false, sample_n: 10, sample_dt: NS_PER_MS * 200)
|
68
56
|
raise ArgumentError, "No inputs specified" if inputs.empty?
|
69
57
|
|
@@ -75,16 +63,9 @@ module Benchmark
|
|
75
63
|
def_bench!
|
76
64
|
end
|
77
65
|
|
78
|
-
# Indicates whether input values will be +dup+-ed before they are
|
79
|
-
# passed to a {report} block. Defaults to +false+. This should
|
80
|
-
# be set to +true+ if {report} blocks destructively modify their
|
81
|
-
# arguments.
|
82
|
-
#
|
83
66
|
# @return [Boolean]
|
84
67
|
attr_reader :dup_inputs
|
85
68
|
|
86
|
-
# See {dup_inputs}.
|
87
|
-
#
|
88
69
|
# @param flag [Boolean]
|
89
70
|
# @return [Boolean]
|
90
71
|
def dup_inputs=(flag)
|
@@ -93,14 +74,9 @@ module Benchmark
|
|
93
74
|
@dup_inputs
|
94
75
|
end
|
95
76
|
|
96
|
-
# The number of samples to take when benchmarking. Defaults to 10.
|
97
|
-
#
|
98
77
|
# @return [Integer]
|
99
78
|
attr_accessor :sample_n
|
100
79
|
|
101
|
-
# The approximate duration of time (in nanoseconds) each sample
|
102
|
-
# should take when benchmarking. Defaults to 200,000 nanoseconds.
|
103
|
-
#
|
104
80
|
# @return [Integer]
|
105
81
|
attr_accessor :sample_dt
|
106
82
|
|
@@ -110,18 +86,16 @@ module Benchmark
|
|
110
86
|
# @return [Array<Benchmark::Inputs::Report>]
|
111
87
|
attr_reader :reports
|
112
88
|
|
113
|
-
# Benchmarks the given block using the
|
114
|
-
#
|
115
|
-
#
|
116
|
-
#
|
117
|
-
# {
|
89
|
+
# Benchmarks the given block using each of the Job's input values.
|
90
|
+
# If {dup_inputs} is true, each input value is +dup+'d before
|
91
|
+
# being yielded to the block. Prints the block's estimated speed
|
92
|
+
# (in invocations per second) to +$stdout+, and adds a {Report} to
|
93
|
+
# {reports}.
|
118
94
|
#
|
119
95
|
# @param label [String]
|
120
|
-
#
|
121
|
-
# @yield [input]
|
122
|
-
# action to benchmark
|
96
|
+
# Label for the report
|
123
97
|
# @yieldparam input [Object]
|
124
|
-
#
|
98
|
+
# One of the Job's input values
|
125
99
|
# @return [void]
|
126
100
|
def report(label)
|
127
101
|
# estimate repititions
|
@@ -148,7 +122,7 @@ module Benchmark
|
|
148
122
|
end
|
149
123
|
|
150
124
|
# Prints the relative speeds (from fastest to slowest) of all
|
151
|
-
# {
|
125
|
+
# {reports} to +$stdout+.
|
152
126
|
#
|
153
127
|
# @return [void]
|
154
128
|
def compare!
|
@@ -210,9 +184,11 @@ module Benchmark
|
|
210
184
|
# @return [String]
|
211
185
|
attr_reader :label
|
212
186
|
|
213
|
-
# The ratio of
|
214
|
-
#
|
215
|
-
#
|
187
|
+
# The ratio of the speed from the fastest report compared to the
|
188
|
+
# speed from this report. In other words, the "slower than
|
189
|
+
# fastest by" multiplier for this report. Will be +nil+ if the
|
190
|
+
# absolute difference in speed between the two reports falls
|
191
|
+
# within the combined measurement error.
|
216
192
|
#
|
217
193
|
# This value is set by {Benchmark::Inputs::Job#compare!}.
|
218
194
|
#
|
@@ -243,14 +219,14 @@ module Benchmark
|
|
243
219
|
@stddev = nil
|
244
220
|
end
|
245
221
|
|
246
|
-
# The estimated
|
222
|
+
# The estimated speed for the report, in invocations per second.
|
247
223
|
#
|
248
224
|
# @return [Float]
|
249
225
|
def ips
|
250
226
|
@mean
|
251
227
|
end
|
252
228
|
|
253
|
-
# The
|
229
|
+
# The standard deviation of the estimated speed for the report.
|
254
230
|
#
|
255
231
|
# @return [Float]
|
256
232
|
def stddev
|
metadata
CHANGED
@@ -1,74 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: benchmark-inputs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Hefner
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
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: '1.12'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '1.12'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rake
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '10.0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '10.0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: minitest
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '5.0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '5.0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: yard
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0.9'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0.9'
|
11
|
+
date: 2020-09-06 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
69
13
|
description:
|
70
14
|
email:
|
71
|
-
- jonathan
|
15
|
+
- jonathan@hefner.pro
|
72
16
|
executables: []
|
73
17
|
extensions: []
|
74
18
|
extra_rdoc_files: []
|
@@ -86,7 +30,10 @@ files:
|
|
86
30
|
homepage: https://github.com/jonathanhefner/benchmark-inputs
|
87
31
|
licenses:
|
88
32
|
- MIT
|
89
|
-
metadata:
|
33
|
+
metadata:
|
34
|
+
homepage_uri: https://github.com/jonathanhefner/benchmark-inputs
|
35
|
+
source_code_uri: https://github.com/jonathanhefner/benchmark-inputs
|
36
|
+
changelog_uri: https://github.com/jonathanhefner/benchmark-inputs/blob/master/CHANGELOG.md
|
90
37
|
post_install_message:
|
91
38
|
rdoc_options: []
|
92
39
|
require_paths:
|
@@ -95,14 +42,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
95
42
|
requirements:
|
96
43
|
- - ">="
|
97
44
|
- !ruby/object:Gem::Version
|
98
|
-
version: '
|
45
|
+
version: '2.2'
|
99
46
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
47
|
requirements:
|
101
48
|
- - ">="
|
102
49
|
- !ruby/object:Gem::Version
|
103
50
|
version: '0'
|
104
51
|
requirements: []
|
105
|
-
rubygems_version: 3.
|
52
|
+
rubygems_version: 3.1.2
|
106
53
|
signing_key:
|
107
54
|
specification_version: 4
|
108
55
|
summary: Input-focused benchmarking
|