benchmark-ips 2.3.0 → 2.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/History.md +223 -0
- data/LICENSE +20 -0
- data/README.md +106 -29
- data/examples/advanced.rb +20 -0
- data/examples/hold.rb +41 -0
- data/examples/save.rb +50 -0
- data/examples/simple.rb +47 -0
- data/lib/benchmark/compare.rb +59 -23
- data/lib/benchmark/ips/job/entry.rb +95 -0
- data/lib/benchmark/ips/job/noop_report.rb +27 -0
- data/lib/benchmark/ips/job/stdout_report.rb +64 -0
- data/lib/benchmark/ips/job.rb +211 -150
- data/lib/benchmark/ips/noop_suite.rb +25 -0
- data/lib/benchmark/ips/report.rb +46 -27
- data/lib/benchmark/ips/share.rb +50 -0
- data/lib/benchmark/ips/stats/bootstrap.rb +58 -0
- data/lib/benchmark/ips/stats/sd.rb +45 -0
- data/lib/benchmark/ips/stats/stats_metric.rb +21 -0
- data/lib/benchmark/ips.rb +91 -24
- data/lib/benchmark/timing.rb +39 -16
- metadata +24 -31
- data/.autotest +0 -23
- data/.gemtest +0 -0
- data/History.txt +0 -87
- data/Manifest.txt +0 -11
- data/Rakefile +0 -26
- data/test/test_benchmark_ips.rb +0 -161
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0516f3e1e35f43a8fe32a6f32357aa124478ba54228ffe57d928cfc1231851bc
|
4
|
+
data.tar.gz: d62da6a6c1d2696b7667bd125ffe6bb2c33b3d61da5c393e729d7ca8a3d70ee7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b644d293980f1ac9e3158abbe4f2c9d44d23185878edb9cb3861f3ca4f6837d557f89f8eb19bfcc42a45f53f3d112f2fe3ab22fc85a9633ede7e678b5fb90336
|
7
|
+
data.tar.gz: afe9972cdecdb2f42d4946afbac3d02cb3ead3a3d47a804960026ea77487cf885f6ddd7368edb13c522ee11e251599bf953d3d9a8172411c10e7259f7e9352b2
|
data/History.md
ADDED
@@ -0,0 +1,223 @@
|
|
1
|
+
### 2.10.0 / 2022-02-17
|
2
|
+
|
3
|
+
* Feature
|
4
|
+
* Adds :order option to compare, with new `:baseline` order which compares all
|
5
|
+
variations against the first option benchmarked.
|
6
|
+
|
7
|
+
### 2.9.3 / 2022-01-25
|
8
|
+
|
9
|
+
* Bug fix
|
10
|
+
* All warmups and benchmarks must run at least once
|
11
|
+
|
12
|
+
### 2.9.2 / 2021-10-10
|
13
|
+
|
14
|
+
* Bug fix
|
15
|
+
* Fix a problem with certain configs of quiet mode
|
16
|
+
|
17
|
+
### 2.9.1 / 2021-05-24
|
18
|
+
|
19
|
+
* Bug fix
|
20
|
+
* Include all files in gem
|
21
|
+
|
22
|
+
### 2.9.0 / 2021-05-21
|
23
|
+
|
24
|
+
* Features
|
25
|
+
* Suite can now be set via an accessor
|
26
|
+
* Default SHARE_URL is now `ips.fastruby.io`, operated by Ombu Labs.
|
27
|
+
|
28
|
+
### 2.8.4 / 2020-12-03
|
29
|
+
|
30
|
+
* Bug fix
|
31
|
+
* Fixed hold! when results file does not exist.
|
32
|
+
|
33
|
+
### 2.8.3 / 2020-08-28
|
34
|
+
|
35
|
+
* Bug fix
|
36
|
+
* Fixed inaccuracy caused by integer overflows.
|
37
|
+
|
38
|
+
### 2.8.2 / 2020-05-04
|
39
|
+
|
40
|
+
* Bug fix
|
41
|
+
* Fixed problems with Manifest.txt.
|
42
|
+
* Empty interim results files are ignored.
|
43
|
+
|
44
|
+
### 2.8.0 / 2020-05-01
|
45
|
+
|
46
|
+
* Feature
|
47
|
+
* Allow running with empty ips block.
|
48
|
+
* Added save! method for saving interim results.
|
49
|
+
* Run more than just 1 cycle during warmup to reduce overhead.
|
50
|
+
* Optimized Job::Entry hot-path for fairer results on JRuby/TruffleRuby.
|
51
|
+
|
52
|
+
* Bug fix
|
53
|
+
* Removed the warmup section if set to 0.
|
54
|
+
* Added some RDoc docs.
|
55
|
+
* Added some examples in examples/
|
56
|
+
|
57
|
+
### 2.7.2 / 2016-08-18
|
58
|
+
|
59
|
+
* 1 bug fix:
|
60
|
+
* Restore old accessors. Fixes #76
|
61
|
+
|
62
|
+
### 2.7.1 / 2016-08-08
|
63
|
+
|
64
|
+
Add missing files
|
65
|
+
|
66
|
+
### 2.7.0 / 2016-08-05
|
67
|
+
|
68
|
+
* 1 minor features:
|
69
|
+
* Add support for confidence intervals
|
70
|
+
|
71
|
+
* 1 bug fixes:
|
72
|
+
* Cleanup a few coding patterns
|
73
|
+
|
74
|
+
* 2 doc fixes:
|
75
|
+
* Add infos about benchark.fyi to Readme
|
76
|
+
* Remove ancient releases
|
77
|
+
|
78
|
+
* 3 merged PRs:
|
79
|
+
* Merge pull request #65 from kbrock/fixup_inject
|
80
|
+
* Merge pull request #67 from benoittgt/master
|
81
|
+
* Merge pull request #69 from chrisseaton/kalibera-confidence-intervals
|
82
|
+
|
83
|
+
### MISSING 2.6.0 and 2.6.1
|
84
|
+
|
85
|
+
### 2.5.0 / 2016-02-14
|
86
|
+
|
87
|
+
* 1 minor feature:
|
88
|
+
* Add iterations option.
|
89
|
+
|
90
|
+
* 1 bug fixes:
|
91
|
+
* Don't tell people something is slower if it's within the error.
|
92
|
+
|
93
|
+
* 2 merged PRs:
|
94
|
+
* Merge pull request #58 from chrisseaton/iterations
|
95
|
+
* Merge pull request #60 from chrisseaton/significance
|
96
|
+
|
97
|
+
### 2.4.1 / 2016-02-12
|
98
|
+
|
99
|
+
* 1 bug fix:
|
100
|
+
* Add missing files to gem
|
101
|
+
|
102
|
+
### 2.4.0 / 2016-02-12
|
103
|
+
|
104
|
+
* 1 minor features
|
105
|
+
* Add support for hold! and independent invocations.
|
106
|
+
|
107
|
+
* 6 bug fixes
|
108
|
+
* Separate messages for warming up and calculating.
|
109
|
+
* Tighten timing loop.
|
110
|
+
* Pass simple types into Job#create_report
|
111
|
+
* More concise sorting
|
112
|
+
* Fix runtime comparison
|
113
|
+
* Use runtime if ips is not available
|
114
|
+
|
115
|
+
* 5 doc fixes
|
116
|
+
* Fix typo unsed --> used
|
117
|
+
* Better document Report::Entry
|
118
|
+
* Fix some typos in docs
|
119
|
+
* Don't calculate mean 2 times
|
120
|
+
* Add more tolerance to tests
|
121
|
+
|
122
|
+
* 13 merged PRs
|
123
|
+
* Merge pull request #44 from kbrock/job_extract
|
124
|
+
* Merge pull request #45 from kbrock/runtime_only
|
125
|
+
* Merge pull request #47 from kbrock/use_avg
|
126
|
+
* Merge pull request #46 from kbrock/report_stdout
|
127
|
+
* Merge pull request #48 from bquorning/fix-label-for-runtime-comparison
|
128
|
+
* Merge pull request #50 from tjschuck/fix_typo
|
129
|
+
* Merge pull request #51 from bquorning/all-reports-respond-to-ips
|
130
|
+
* Merge pull request #52 from kbrock/document_reports
|
131
|
+
* Merge pull request #53 from kbrock/interface_create_report
|
132
|
+
* Merge pull request #54 from PragTob/patch-2
|
133
|
+
* Merge pull request #55 from chrisseaton/messages
|
134
|
+
* Merge pull request #56 from chrisseaton/independence
|
135
|
+
* Merge pull request #57 from chrisseaton/tighten-loop
|
136
|
+
|
137
|
+
### 2.3.0 / 2015-07-20
|
138
|
+
|
139
|
+
* 2 minor features:
|
140
|
+
* Support keyword arguments
|
141
|
+
* Allow any datatype for labels (use #to_s conversion)
|
142
|
+
|
143
|
+
* 1 doc/test changes:
|
144
|
+
* Newer Travis for 1.8.7, ree, and 2.2.2
|
145
|
+
|
146
|
+
* 3 PRs merged:
|
147
|
+
* Merge pull request #41 from kbrock/kwargs-support
|
148
|
+
* Merge pull request #42 from kbrock/newer_travis
|
149
|
+
* Merge pull request #43 from kbrock/non_to_s_labels
|
150
|
+
|
151
|
+
### 2.2.0 / 2015-05-09
|
152
|
+
|
153
|
+
* 1 minor features:
|
154
|
+
* Fix quiet mode
|
155
|
+
* Allow passing a custom suite via config
|
156
|
+
* Silent a job if a suite was passed and is quiet
|
157
|
+
* Export report to json file.
|
158
|
+
* Accept symbol as report's argument.
|
159
|
+
|
160
|
+
* 2 doc fixes:
|
161
|
+
* Squish duplicate `to` in README
|
162
|
+
* Update copyright to 2015. [ci skip]
|
163
|
+
|
164
|
+
* 9 PRs merged:
|
165
|
+
* Merge pull request #37 from splattael/patch-1
|
166
|
+
* Merge pull request #36 from kirs/quiet-mode
|
167
|
+
* Merge pull request #35 from JuanitoFatas/doc/suite
|
168
|
+
* Merge pull request #34 from splattael/config-suite
|
169
|
+
* Merge pull request #33 from splattael/suite-quiet
|
170
|
+
* Merge pull request #32 from O-I/remove-gemfile-lock
|
171
|
+
* Merge pull request #31 from JuanitoFatas/doc/bump-copyright-year
|
172
|
+
* Merge pull request #29 from JuanitoFatas/feature/json-export
|
173
|
+
* Merge pull request #26 from JuanitoFatas/feature/takes-symbol-as-report-parameter
|
174
|
+
|
175
|
+
### 2.1.1 / 2015-01-12
|
176
|
+
|
177
|
+
* 1 minor fix:
|
178
|
+
* Don't send label through printf so that % work directly
|
179
|
+
|
180
|
+
* 1 documenation changes:
|
181
|
+
* Use HEREDOC and wrap at 80 chars for example result description
|
182
|
+
|
183
|
+
* 1 usage fix:
|
184
|
+
* Add gemspec for use via bundler git
|
185
|
+
|
186
|
+
* 1 PR merged:
|
187
|
+
* Merge pull request #24 from zzak/simple-format-result-description
|
188
|
+
|
189
|
+
### 2.1.0 / 2014-11-10
|
190
|
+
|
191
|
+
* Documentation changes:
|
192
|
+
* Many documentation fixes by Juanito Fatas!
|
193
|
+
* Minor readme fix by Will Leinweber
|
194
|
+
|
195
|
+
* 2 minor features:
|
196
|
+
* Displaying the total runtime for a job is suppressed unless interesting
|
197
|
+
* Formatting of large values improved (human vs raw mode)
|
198
|
+
* Contributed by Charles Oliver Nutter
|
199
|
+
|
200
|
+
### 2.0.0 / 2014-06-18
|
201
|
+
|
202
|
+
* The 'Davy Stevenson' release!
|
203
|
+
* Codename: Springtime Hummingbird Dance
|
204
|
+
|
205
|
+
* Big API refactoring so the internal bits are easier to use
|
206
|
+
* Bump to 2.0 because return types changed to make the API better
|
207
|
+
|
208
|
+
* Contributors added:
|
209
|
+
* Davy Stevenson
|
210
|
+
* Juanito Fatas
|
211
|
+
* Benoit Daloze
|
212
|
+
* Matias
|
213
|
+
* Tony Arcieri
|
214
|
+
* Vipul A M
|
215
|
+
* Zachary Scott
|
216
|
+
* schneems (Richard Schneeman)
|
217
|
+
|
218
|
+
### 1.0.0 / 2012-03-23
|
219
|
+
|
220
|
+
* 1 major enhancement
|
221
|
+
|
222
|
+
* Birthday!
|
223
|
+
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2015 Evan Phoenix
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
'Software'), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
17
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
18
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
19
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
20
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,16 +1,17 @@
|
|
1
|
+
# benchmark-ips
|
2
|
+
|
3
|
+
* rdoc :: http://rubydoc.info/gems/benchmark-ips
|
4
|
+
* home :: https://github.com/evanphx/benchmark-ips
|
5
|
+
|
1
6
|
[![Gem Version](https://badge.fury.io/rb/benchmark-ips.svg)](http://badge.fury.io/rb/benchmark-ips)
|
2
7
|
[![Build Status](https://secure.travis-ci.org/evanphx/benchmark-ips.svg)](http://travis-ci.org/evanphx/benchmark-ips)
|
3
8
|
[![Inline docs](http://inch-ci.org/github/evanphx/benchmark-ips.svg)](http://inch-ci.org/github/evanphx/benchmark-ips)
|
4
9
|
|
5
|
-
# benchmark-ips
|
6
|
-
|
7
10
|
* https://github.com/evanphx/benchmark-ips
|
8
11
|
|
9
|
-
* [documentation](http://rubydoc.info/gems/benchmark-ips)
|
10
|
-
|
11
12
|
## DESCRIPTION:
|
12
13
|
|
13
|
-
|
14
|
+
An iterations per second enhancement to Benchmark.
|
14
15
|
|
15
16
|
## FEATURES/PROBLEMS:
|
16
17
|
|
@@ -136,6 +137,106 @@ Benchmark.ips do |x|
|
|
136
137
|
end
|
137
138
|
```
|
138
139
|
|
140
|
+
### Independent benchmarking
|
141
|
+
|
142
|
+
If you are comparing multiple implementations of a piece of code you may want
|
143
|
+
to benchmark them in separate invocations of Ruby so that the measurements
|
144
|
+
are independent of each other. You can do this with the `hold!` command.
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
Benchmark.ips do |x|
|
148
|
+
|
149
|
+
# Hold results between multiple invocations of Ruby
|
150
|
+
x.hold! 'filename'
|
151
|
+
|
152
|
+
end
|
153
|
+
```
|
154
|
+
|
155
|
+
This will run only one benchmarks each time you run the command, storing
|
156
|
+
results in the specified file. The file is deleted when all results have been
|
157
|
+
gathered and the report is shown.
|
158
|
+
|
159
|
+
Alternatively, if you prefer a different approach, the `save!` command is
|
160
|
+
available. Examples for [hold!](examples/hold.rb) and [save!](examples/save.rb) are available in
|
161
|
+
the `examples/` directory.
|
162
|
+
|
163
|
+
|
164
|
+
### Multiple iterations
|
165
|
+
|
166
|
+
In some cases you may want to run multiple iterations of the warmup and
|
167
|
+
calculation stages and take only the last result for comparison. This is useful
|
168
|
+
if you are benchmarking with an implementation of Ruby that optimizes using
|
169
|
+
tracing or on-stack-replacement, because to those implementations the
|
170
|
+
calculation phase may appear as new, unoptimized code.
|
171
|
+
|
172
|
+
You can do this with the `iterations` option, which by default is `1`. The
|
173
|
+
total time spent will then be `iterations * warmup + iterations * time` seconds.
|
174
|
+
|
175
|
+
```ruby
|
176
|
+
Benchmark.ips do |x|
|
177
|
+
|
178
|
+
x.config(:iterations => 3)
|
179
|
+
|
180
|
+
# or
|
181
|
+
|
182
|
+
x.iterations = 3
|
183
|
+
|
184
|
+
end
|
185
|
+
```
|
186
|
+
|
187
|
+
### Online sharing
|
188
|
+
|
189
|
+
If you want to quickly share your benchmark result with others, run you benchmark
|
190
|
+
with `SHARE=1` argument. For example: `SHARE=1 ruby my_benchmark.rb`.
|
191
|
+
|
192
|
+
Result will be sent to [benchmark.fyi](https://ips.fastruby.io/) and benchmark-ips
|
193
|
+
will display the link to share the benchmark's result.
|
194
|
+
|
195
|
+
If you want to run your own instance of [benchmark.fyi](https://github.com/evanphx/benchmark.fyi)
|
196
|
+
and share it to that instance, you can do this: `SHARE_URL=https://ips.example.com ruby my_benchmark.rb`
|
197
|
+
|
198
|
+
### Advanced Statistics
|
199
|
+
|
200
|
+
By default, the margin of error shown is plus-minus one standard deviation. If
|
201
|
+
a more advanced statistical test is wanted, a bootstrap confidence interval
|
202
|
+
can be calculated instead. A bootstrap confidence interval has the advantages of
|
203
|
+
arguably being more mathematically sound for this application than a standard
|
204
|
+
deviation, it additionally produces an error for relative slowdowns, which the
|
205
|
+
standard deviation does not, and it is arguably more intuitive and actionable.
|
206
|
+
|
207
|
+
When a bootstrap confidence interval is used, a median of the interval is used
|
208
|
+
rather than the mean of the samples, which is what you get with the default
|
209
|
+
standard deviation.
|
210
|
+
|
211
|
+
The bootstrap confidence interval used is the one described by Tomas Kalibera.
|
212
|
+
Note that for this technique to be valid your benchmark should have reached a
|
213
|
+
non-periodic steady state with statistically independent samples (it should
|
214
|
+
have warmed up) by the time measurements start.
|
215
|
+
|
216
|
+
Using a bootstrap confidence internal requires that the 'kalibera' gem is
|
217
|
+
installed separately. This gem is not a formal dependency, as by default it is
|
218
|
+
not needed.
|
219
|
+
|
220
|
+
```
|
221
|
+
gem install kalibera
|
222
|
+
```
|
223
|
+
|
224
|
+
```ruby
|
225
|
+
Benchmark.ips do |x|
|
226
|
+
|
227
|
+
# The default is :stats => :sd, which doesn't have a configurable confidence
|
228
|
+
x.config(:stats => :bootstrap, :confidence => 95)
|
229
|
+
|
230
|
+
# or
|
231
|
+
|
232
|
+
x.stats = :bootstrap
|
233
|
+
x.confidence = 95
|
234
|
+
|
235
|
+
# confidence is 95% by default, so it can be omitted
|
236
|
+
|
237
|
+
end
|
238
|
+
```
|
239
|
+
|
139
240
|
## REQUIREMENTS:
|
140
241
|
|
141
242
|
* None!
|
@@ -153,27 +254,3 @@ After checking out the source, run:
|
|
153
254
|
This task will install any missing dependencies, run the tests/specs,
|
154
255
|
and generate the RDoc.
|
155
256
|
|
156
|
-
## LICENSE:
|
157
|
-
|
158
|
-
(The MIT License)
|
159
|
-
|
160
|
-
Copyright (c) 2015 Evan Phoenix
|
161
|
-
|
162
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
163
|
-
a copy of this software and associated documentation files (the
|
164
|
-
'Software'), to deal in the Software without restriction, including
|
165
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
166
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
167
|
-
permit persons to whom the Software is furnished to do so, subject to
|
168
|
-
the following conditions:
|
169
|
-
|
170
|
-
The above copyright notice and this permission notice shall be
|
171
|
-
included in all copies or substantial portions of the Software.
|
172
|
-
|
173
|
-
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
174
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
175
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
176
|
-
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
177
|
-
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
178
|
-
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
179
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'benchmark/ips'
|
4
|
+
|
5
|
+
Benchmark.ips do |x|
|
6
|
+
|
7
|
+
# Use bootstrap confidence intervals
|
8
|
+
x.stats = :bootstrap
|
9
|
+
|
10
|
+
# Set confidence to 95%
|
11
|
+
x.confidence = 95
|
12
|
+
|
13
|
+
# Run multiple iterations for better warmup
|
14
|
+
x.iterations = 3
|
15
|
+
|
16
|
+
x.report("mul") { 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 }
|
17
|
+
x.report("pow") { 2 ** 8 }
|
18
|
+
|
19
|
+
x.compare!
|
20
|
+
end
|
data/examples/hold.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# example to explain hold! usage https://github.com/evanphx/benchmark-ips/issues/85
|
3
|
+
# The hold! feature expects to be run twice, generally with different Rubys.
|
4
|
+
# hold! can also be used to compare modules changes which impact the run time
|
5
|
+
# RUN_1: ruby examples/hold.rb
|
6
|
+
# Warming up --------------------------------------
|
7
|
+
# without 172.168k i/100ms
|
8
|
+
# Calculating -------------------------------------
|
9
|
+
# without 2.656M (± 3.3%) i/s - 13.429M in 5.062098s
|
10
|
+
#
|
11
|
+
# RUN_2: WITH_MODULE=true ruby examples/hold.rb
|
12
|
+
# Warming up --------------------------------------
|
13
|
+
# with 92.087k i/100ms
|
14
|
+
# Calculating -------------------------------------
|
15
|
+
# with 1.158M (± 1.4%) i/s - 5.801M in 5.010084s
|
16
|
+
#
|
17
|
+
# Comparison:
|
18
|
+
# without: 2464721.3 i/s
|
19
|
+
# with: 1158179.6 i/s - 2.13x slower
|
20
|
+
require 'benchmark/ips'
|
21
|
+
|
22
|
+
Benchmark.ips do |x|
|
23
|
+
x.report('without') do
|
24
|
+
'Bruce'.inspect
|
25
|
+
end
|
26
|
+
|
27
|
+
if ENV['WITH_MODULE'] == 'true'
|
28
|
+
class String
|
29
|
+
def inspect
|
30
|
+
result = %w[Bruce Wayne is Batman]
|
31
|
+
result.join(' ')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
x.report('with') do
|
37
|
+
'Bruce'.inspect
|
38
|
+
end
|
39
|
+
x.hold! 'temp_results'
|
40
|
+
x.compare!
|
41
|
+
end
|
data/examples/save.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# example to explain save!
|
4
|
+
# The save! feature expects to be run twice, generally with different Rubys.
|
5
|
+
# save! can also be used to compare modules changes which impact the run time
|
6
|
+
#
|
7
|
+
# If you're comparing ruby versions, Just use the version in the label
|
8
|
+
#
|
9
|
+
# x.report("ruby #{RUBY_VERSION}") { 'Bruce'.inspect }
|
10
|
+
#
|
11
|
+
# Or use a hash
|
12
|
+
#
|
13
|
+
# x.report("version" => RUBY_VERSION, "method" => 'bruce') { 'Bruce'.inspect }
|
14
|
+
#
|
15
|
+
# RUN_1: SAVE_FILE='run1.out' ruby examples/hold.rb
|
16
|
+
# Warming up --------------------------------------
|
17
|
+
# without 172.168k i/100ms
|
18
|
+
# Calculating -------------------------------------
|
19
|
+
# without 2.656M (± 3.3%) i/s - 13.429M in 5.062098s
|
20
|
+
#
|
21
|
+
# RUN_2: SAVE_FILE='run1.out' WITH_MODULE=true ruby examples/hold.rb
|
22
|
+
# Warming up --------------------------------------
|
23
|
+
# with 92.087k i/100ms
|
24
|
+
# Calculating -------------------------------------
|
25
|
+
# with 1.158M (± 1.4%) i/s - 5.801M in 5.010084s
|
26
|
+
#
|
27
|
+
# Comparison:
|
28
|
+
# without: 2464721.3 i/s
|
29
|
+
# with: 1158179.6 i/s - 2.13x slower
|
30
|
+
# CLEANUP: rm run1.out
|
31
|
+
|
32
|
+
require 'benchmark/ips'
|
33
|
+
|
34
|
+
Benchmark.ips do |x|
|
35
|
+
x.report(ENV['WITH_MODULE'] == 'true' ? 'with' : 'without') do
|
36
|
+
'Bruce'.inspect
|
37
|
+
end
|
38
|
+
|
39
|
+
if ENV['WITH_MODULE'] == 'true'
|
40
|
+
class String
|
41
|
+
def inspect
|
42
|
+
result = %w[Bruce Wayne is Batman]
|
43
|
+
result.join(' ')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
x.save! ENV['SAVE_FILE'] if ENV['SAVE_FILE']
|
49
|
+
x.compare!
|
50
|
+
end
|
data/examples/simple.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'benchmark/ips'
|
4
|
+
|
5
|
+
Benchmark.ips do |x|
|
6
|
+
|
7
|
+
# Configure the number of seconds used during
|
8
|
+
# the warmup phase and calculation phase
|
9
|
+
x.config(:time => 5, :warmup => 2)
|
10
|
+
|
11
|
+
# These parameters can also be configured this way
|
12
|
+
x.time = 5
|
13
|
+
x.warmup = 2
|
14
|
+
|
15
|
+
# Typical mode, runs the block as many times as it can
|
16
|
+
x.report("addition") { 1 + 2 }
|
17
|
+
|
18
|
+
# To reduce overhead, the number of iterations is passed in
|
19
|
+
# and the block must run the code the specific number of times.
|
20
|
+
# Used for when the workload is very small and any overhead
|
21
|
+
# introduces incorrectable errors.
|
22
|
+
x.report(:addition2) do |times|
|
23
|
+
i = 0
|
24
|
+
while i < times
|
25
|
+
1 + 2
|
26
|
+
i += 1
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# To reduce overhead even more, grafts the code given into
|
31
|
+
# the loop that performs the iterations internally to reduce
|
32
|
+
# overhead. Typically not needed, use the |times| form instead.
|
33
|
+
x.report("addition3", "1 + 2")
|
34
|
+
|
35
|
+
# Really long labels should be formatted correctly
|
36
|
+
x.report("addition-test-long-label") { 1 + 2 }
|
37
|
+
|
38
|
+
x.compare!
|
39
|
+
end
|
40
|
+
|
41
|
+
puts <<-EOD
|
42
|
+
Typical results will show addition2 & addition3 to be the most performant, and
|
43
|
+
they should perform reasonably similarly. You should see addition and
|
44
|
+
addition-test-long-label to perform very similarly to each other (as they are
|
45
|
+
running the same test, just with different labels), and they should both run in
|
46
|
+
the neighborhood of 3.5 times slower than addition2 and addition3."
|
47
|
+
EOD
|
data/lib/benchmark/compare.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Benchmark
|
2
4
|
# Functionality of performaing comparison between reports.
|
3
5
|
#
|
@@ -24,46 +26,80 @@ module Benchmark
|
|
24
26
|
# Reduce using to_proc: 247295.4 i/s - 1.13x slower
|
25
27
|
#
|
26
28
|
# Besides regular Calculating report, this will also indicates which one is slower.
|
29
|
+
#
|
30
|
+
# +x.compare!+ also takes an +order: :baseline+ option.
|
31
|
+
#
|
32
|
+
# Example:
|
33
|
+
# > Benchmark.ips do |x|
|
34
|
+
# x.report('Reduce using block') { [*1..10].reduce { |sum, n| sum + n } }
|
35
|
+
# x.report('Reduce using tag') { [*1..10].reduce(:+) }
|
36
|
+
# x.report('Reduce using to_proc') { [*1..10].reduce(&:+) }
|
37
|
+
# x.compare!(order: :baseline)
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# Calculating -------------------------------------
|
41
|
+
# Reduce using block 886.202k (± 2.2%) i/s - 4.521M in 5.103774s
|
42
|
+
# Reduce using tag 1.821M (± 1.6%) i/s - 9.111M in 5.004183s
|
43
|
+
# Reduce using to_proc 895.948k (± 1.6%) i/s - 4.528M in 5.055368s
|
44
|
+
#
|
45
|
+
# Comparison:
|
46
|
+
# Reduce using block: 886202.5 i/s
|
47
|
+
# Reduce using tag: 1821055.0 i/s - 2.05x (± 0.00) faster
|
48
|
+
# Reduce using to_proc: 895948.1 i/s - same-ish: difference falls within error
|
49
|
+
#
|
50
|
+
# The first report is considered the baseline against which other reports are compared.
|
27
51
|
module Compare
|
28
52
|
|
29
53
|
# Compare between reports, prints out facts of each report:
|
30
54
|
# runtime, comparative speed difference.
|
31
|
-
# @param
|
32
|
-
def compare(*
|
33
|
-
return if
|
55
|
+
# @param entries [Array<Report::Entry>] Reports to compare.
|
56
|
+
def compare(*entries, order: :fastest)
|
57
|
+
return if entries.size < 2
|
34
58
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
59
|
+
case order
|
60
|
+
when :baseline
|
61
|
+
baseline = entries.shift
|
62
|
+
sorted = entries.sort_by{ |e| e.stats.central_tendency }.reverse
|
63
|
+
when :fastest
|
64
|
+
sorted = entries.sort_by{ |e| e.stats.central_tendency }.reverse
|
65
|
+
baseline = sorted.shift
|
66
|
+
else
|
67
|
+
raise ArgumentError, "Unknwon order: #{order.inspect}"
|
43
68
|
end
|
44
69
|
|
45
|
-
best = sorted.shift
|
46
|
-
|
47
70
|
$stdout.puts "\nComparison:"
|
48
71
|
|
49
|
-
|
50
|
-
$stdout.printf "%20s: %10.1f i/s\n", best.label, best.ips
|
51
|
-
else
|
52
|
-
$stdout.puts "#{best.rjust(20)}: #{best.runtime}s"
|
53
|
-
end
|
72
|
+
$stdout.printf "%20s: %10.1f i/s\n", baseline.label.to_s, baseline.stats.central_tendency
|
54
73
|
|
55
74
|
sorted.each do |report|
|
56
75
|
name = report.label.to_s
|
57
76
|
|
58
|
-
|
59
|
-
|
60
|
-
|
77
|
+
$stdout.printf "%20s: %10.1f i/s - ", name, report.stats.central_tendency
|
78
|
+
|
79
|
+
if report.stats.overlaps?(baseline.stats)
|
80
|
+
$stdout.print "same-ish: difference falls within error"
|
81
|
+
elsif report.stats.central_tendency > baseline.stats.central_tendency
|
82
|
+
speedup, error = report.stats.speedup(baseline.stats)
|
83
|
+
$stdout.printf "%.2fx ", speedup
|
84
|
+
if error
|
85
|
+
$stdout.printf " (± %.2f)", error
|
86
|
+
end
|
87
|
+
$stdout.print " faster"
|
61
88
|
else
|
62
|
-
|
63
|
-
$stdout.
|
89
|
+
slowdown, error = report.stats.slowdown(baseline.stats)
|
90
|
+
$stdout.printf "%.2fx ", slowdown
|
91
|
+
if error
|
92
|
+
$stdout.printf " (± %.2f)", error
|
93
|
+
end
|
94
|
+
$stdout.print " slower"
|
64
95
|
end
|
96
|
+
|
97
|
+
$stdout.puts
|
65
98
|
end
|
66
99
|
|
100
|
+
footer = baseline.stats.footer
|
101
|
+
$stdout.puts footer.rjust(40) if footer
|
102
|
+
|
67
103
|
$stdout.puts
|
68
104
|
end
|
69
105
|
end
|