benchmark-ips 2.13.0 → 2.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +12 -1
- data/README.md +29 -20
- data/examples/quick.rb +17 -0
- data/lib/benchmark/compare.rb +1 -1
- data/lib/benchmark/ips/job.rb +1 -1
- data/lib/benchmark/ips/report.rb +10 -8
- data/lib/benchmark/ips.rb +49 -7
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aaebdee644671b1a757ded5e4868e1035718834832d2cfec8eb4460a3fa33171
|
4
|
+
data.tar.gz: a7349d06bb190b2ea9b7c06caf8da4ba26a48b00e550ca8a71ed1fe22ddff290
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b2cef3b3b852b48eb8cdbaa1b51b728edb0760d77983d5408e81a44d9dfc280f257456a57d8a213155ca0752508c81282e243daf2cbb16d1a95bdaac1b4d211
|
7
|
+
data.tar.gz: 509f946e113907d26745e24a07675684b6870189fcdc36128380b286e774bb03e46a4608b3852aa68e110a2c1e594436e727b9626111bebf1b1a4bdeea7f71f8
|
data/History.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
### 2.14.0 / 2024-09-08
|
2
|
+
|
3
|
+
* Feature
|
4
|
+
* Adds Benchmark::IPS.quick_compare.
|
5
|
+
* Adds absolute duration of each iteration to compare output.
|
6
|
+
|
7
|
+
### 2.13.0 / 2023-12-12
|
8
|
+
|
9
|
+
* Feature
|
10
|
+
* Prints ruby version at top of report.
|
11
|
+
|
1
12
|
### 2.12.0 / 2023-03-08
|
2
13
|
|
3
14
|
* Feature
|
@@ -187,7 +198,7 @@ Add missing files
|
|
187
198
|
* 1 minor fix:
|
188
199
|
* Don't send label through printf so that % work directly
|
189
200
|
|
190
|
-
* 1
|
201
|
+
* 1 documentation changes:
|
191
202
|
* Use HEREDOC and wrap at 80 chars for example result description
|
192
203
|
|
193
204
|
* 1 usage fix:
|
data/README.md
CHANGED
@@ -27,11 +27,7 @@ require 'benchmark/ips'
|
|
27
27
|
Benchmark.ips do |x|
|
28
28
|
# Configure the number of seconds used during
|
29
29
|
# the warmup phase (default 2) and calculation phase (default 5)
|
30
|
-
x.config(:
|
31
|
-
|
32
|
-
# These parameters can also be configured this way
|
33
|
-
x.time = 5
|
34
|
-
x.warmup = 2
|
30
|
+
x.config(warmup: 2, time: 5)
|
35
31
|
|
36
32
|
# Typical mode, runs the block as many times as it can
|
37
33
|
x.report("addition") { 1 + 2 }
|
@@ -43,8 +39,9 @@ Benchmark.ips do |x|
|
|
43
39
|
x.report("addition2") do |times|
|
44
40
|
i = 0
|
45
41
|
while i < times
|
46
|
-
1 + 2
|
47
42
|
i += 1
|
43
|
+
|
44
|
+
1 + 2
|
48
45
|
end
|
49
46
|
end
|
50
47
|
|
@@ -64,24 +61,24 @@ end
|
|
64
61
|
This will generate the following report:
|
65
62
|
|
66
63
|
```
|
67
|
-
|
68
|
-
addition
|
69
|
-
addition2
|
70
|
-
addition3
|
64
|
+
Warming up --------------------------------------
|
65
|
+
addition 3.572M i/100ms
|
66
|
+
addition2 3.672M i/100ms
|
67
|
+
addition3 3.677M i/100ms
|
71
68
|
addition-test-long-label
|
72
|
-
|
73
|
-
|
74
|
-
addition
|
75
|
-
addition2
|
76
|
-
addition3
|
69
|
+
3.511M i/100ms
|
70
|
+
Calculating -------------------------------------
|
71
|
+
addition 36.209M (± 2.8%) i/s (27.62 ns/i) - 182.253M in 5.037433s
|
72
|
+
addition2 36.552M (± 7.8%) i/s (27.36 ns/i) - 183.541M in 5.069987s
|
73
|
+
addition3 36.639M (± 4.8%) i/s (27.29 ns/i) - 182.994M in 5.009234s
|
77
74
|
addition-test-long-label
|
78
|
-
|
75
|
+
36.164M (± 5.8%) i/s (27.65 ns/i) - 181.312M in 5.038364s
|
79
76
|
|
80
77
|
Comparison:
|
81
|
-
addition2:
|
82
|
-
addition3:
|
83
|
-
addition-test-long-label:
|
84
|
-
addition:
|
78
|
+
addition2: 36558904.5 i/s
|
79
|
+
addition3: 36359284.0 i/s - same-ish: difference falls within error
|
80
|
+
addition-test-long-label: 36135428.8 i/s - same-ish: difference falls within error
|
81
|
+
addition: 34666931.3 i/s - same-ish: difference falls within error
|
85
82
|
```
|
86
83
|
|
87
84
|
Benchmark/ips will report the number of iterations per second for a given block
|
@@ -94,6 +91,18 @@ One benefit to using this method is benchmark-ips automatically determines the
|
|
94
91
|
data points for testing our code, so we can focus on the results instead of
|
95
92
|
guessing iteration counts as we do with the traditional Benchmark library.
|
96
93
|
|
94
|
+
You can also use `ips_quick` to save a few lines of code:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
Benchmark.ips_quick(:upcase, :downcase, on: "hello") # runs a suite comparing "hello".upcase and "hello".downcase
|
98
|
+
|
99
|
+
def first; MyJob.perform(1); end
|
100
|
+
def second; MyJobOptimized.perform(1); end
|
101
|
+
Benchmark.ips_quick(:first, :second) # compares :first and :second
|
102
|
+
```
|
103
|
+
|
104
|
+
This adds a very small amount of overhead, which may be significant (i.e. ips_quick will understate the difference) if you're microbenchmarking things that can do over 1 million iterations per second. In that case, you're better off using the full format.
|
105
|
+
|
97
106
|
### Custom Suite
|
98
107
|
|
99
108
|
Pass a custom suite to disable garbage collection during benchmark:
|
data/examples/quick.rb
ADDED
data/lib/benchmark/compare.rb
CHANGED
@@ -64,7 +64,7 @@ module Benchmark
|
|
64
64
|
sorted = entries.sort_by{ |e| e.stats.central_tendency }.reverse
|
65
65
|
baseline = sorted.shift
|
66
66
|
else
|
67
|
-
raise ArgumentError, "
|
67
|
+
raise ArgumentError, "Unknown order: #{order.inspect}"
|
68
68
|
end
|
69
69
|
|
70
70
|
$stdout.puts "\nComparison:"
|
data/lib/benchmark/ips/job.rb
CHANGED
@@ -203,7 +203,7 @@ module Benchmark
|
|
203
203
|
(after.to_f - before.to_f) * MICROSECONDS_PER_SECOND
|
204
204
|
end
|
205
205
|
|
206
|
-
# Calculate the
|
206
|
+
# Calculate the iterations per second given the number
|
207
207
|
# of cycles run and the time in microseconds that elapsed.
|
208
208
|
# @param [Integer] cycles Cycles.
|
209
209
|
# @param [Integer] time_us Time in microsecond.
|
data/lib/benchmark/ips/report.rb
CHANGED
@@ -62,7 +62,7 @@ module Benchmark
|
|
62
62
|
|
63
63
|
# Control if the total time the job took is reported.
|
64
64
|
# Typically this value is not significant because it's very
|
65
|
-
# close to the expected time, so it's
|
65
|
+
# close to the expected time, so it's suppressed by default.
|
66
66
|
def show_total_time!
|
67
67
|
@show_total_time = true
|
68
68
|
end
|
@@ -86,23 +86,25 @@ module Benchmark
|
|
86
86
|
# percentage of standard deviation, iterations in runtime.
|
87
87
|
# @return [String] Left justified body.
|
88
88
|
def body
|
89
|
+
per_iter = (" (%s/i)" % Helpers.humanize_duration(1_000_000_000 / @stats.central_tendency)).rjust(15)
|
90
|
+
|
89
91
|
case Benchmark::IPS.options[:format]
|
90
92
|
when :human
|
91
|
-
left = "%s (±%4.1f%%) i/s" % [Helpers.scale(@stats.central_tendency), @stats.error_percentage]
|
93
|
+
left = ("%s (±%4.1f%%) i/s" % [Helpers.scale(@stats.central_tendency), @stats.error_percentage]).ljust(20)
|
92
94
|
iters = Helpers.scale(@iterations)
|
93
95
|
|
94
96
|
if @show_total_time
|
95
|
-
left
|
97
|
+
left + per_iter + (" - %s in %10.6fs" % [iters, runtime])
|
96
98
|
else
|
97
|
-
left
|
99
|
+
left + per_iter + (" - %s" % iters)
|
98
100
|
end
|
99
101
|
else
|
100
|
-
left = "%10.1f (±%.1f%%) i/s" % [@stats.central_tendency, @stats.error_percentage]
|
102
|
+
left = ("%10.1f (±%.1f%%) i/s" % [@stats.central_tendency, @stats.error_percentage]).ljust(20)
|
101
103
|
|
102
104
|
if @show_total_time
|
103
|
-
left
|
105
|
+
left + per_iter + (" - %10d in %10.6fs" % [@iterations, runtime])
|
104
106
|
else
|
105
|
-
left
|
107
|
+
left + per_iter + (" - %10d" % @iterations)
|
106
108
|
end
|
107
109
|
end
|
108
110
|
end
|
@@ -113,7 +115,7 @@ module Benchmark
|
|
113
115
|
@label.to_s.rjust(20)
|
114
116
|
end
|
115
117
|
|
116
|
-
# Return string
|
118
|
+
# Return string representation of Entry object.
|
117
119
|
# @return [String] Header and body.
|
118
120
|
def to_s
|
119
121
|
"#{header} #{body}"
|
data/lib/benchmark/ips.rb
CHANGED
@@ -13,14 +13,17 @@ require 'benchmark/ips/job'
|
|
13
13
|
# Performance benchmarking library
|
14
14
|
module Benchmark
|
15
15
|
# Benchmark in iterations per second, no more guessing!
|
16
|
-
#
|
16
|
+
#
|
17
|
+
# See Benchmark.ips for documentation on using this gem~
|
18
|
+
#
|
19
|
+
# @see {https://github.com/evanphx/benchmark-ips}
|
17
20
|
module IPS
|
18
21
|
|
19
22
|
# Benchmark-ips Gem version.
|
20
|
-
VERSION = "2.
|
23
|
+
VERSION = "2.14.0"
|
21
24
|
|
22
25
|
# CODENAME of current version.
|
23
|
-
CODENAME = "
|
26
|
+
CODENAME = "Akagi"
|
24
27
|
|
25
28
|
# Measure code in block, each code's benchmarked result will display in
|
26
29
|
# iteration per second with standard deviation in given time.
|
@@ -73,6 +76,32 @@ module Benchmark
|
|
73
76
|
report
|
74
77
|
end
|
75
78
|
|
79
|
+
# Quickly compare multiple methods on the same object.
|
80
|
+
# @param methods [Symbol...] A list of method names (as symbols) to compare.
|
81
|
+
# @param receiver [Object] The object on which to call the methods. Defaults to Kernel.
|
82
|
+
# @param opts [Hash] Additional options for customizing the benchmark.
|
83
|
+
# @option opts [Integer] :warmup The number of seconds to warm up the benchmark.
|
84
|
+
# @option opts [Integer] :time The number of seconds to run the benchmark.
|
85
|
+
#
|
86
|
+
# @example Compare String#upcase and String#downcase
|
87
|
+
# ips_quick(:upcase, :downcase, on: "hello")
|
88
|
+
#
|
89
|
+
# @example Compare two methods you just defined, with a custom warmup.
|
90
|
+
# def add; 1+1; end
|
91
|
+
# def sub; 2-1; end
|
92
|
+
# ips_quick(:add, :sub, warmup: 10)
|
93
|
+
def ips_quick(*methods, on: Kernel, **opts)
|
94
|
+
ips(opts) do |x|
|
95
|
+
x.compare!
|
96
|
+
|
97
|
+
methods.each do |name|
|
98
|
+
x.report(name) do |iter|
|
99
|
+
iter.times { on.__send__ name }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
76
105
|
# Set options for running the benchmarks.
|
77
106
|
# :format => [:human, :raw]
|
78
107
|
# :human format narrows precision and scales results for readability
|
@@ -83,20 +112,33 @@ module Benchmark
|
|
83
112
|
|
84
113
|
module Helpers
|
85
114
|
SUFFIXES = ['', 'k', 'M', 'B', 'T', 'Q'].freeze
|
86
|
-
|
115
|
+
|
87
116
|
def scale(value)
|
88
|
-
scale = (Math.log10(value) / 3).to_i
|
117
|
+
scale = (Math.log10(value) / 3).to_i
|
89
118
|
scale = 0 if scale < 0 || scale >= SUFFIXES.size
|
90
119
|
suffix = SUFFIXES[scale]
|
91
120
|
scaled_value = value.to_f / (1000 ** scale)
|
92
|
-
|
121
|
+
|
93
122
|
"%10.3f#{suffix}" % scaled_value
|
94
123
|
end
|
95
124
|
module_function :scale
|
125
|
+
|
126
|
+
def humanize_duration(duration_ns)
|
127
|
+
if duration_ns < 1000
|
128
|
+
"%.2f ns" % duration_ns
|
129
|
+
elsif duration_ns < 1_000_000
|
130
|
+
"%.2f μs" % (duration_ns / 1000)
|
131
|
+
elsif duration_ns < 1_000_000_000
|
132
|
+
"%.2f ms" % (duration_ns / 1_000_000)
|
133
|
+
else
|
134
|
+
"%.2f s" % (duration_ns / 1_000_000_000)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
module_function :humanize_duration
|
96
138
|
end
|
97
139
|
end
|
98
140
|
|
99
|
-
extend Benchmark::IPS # make ips available as module-level method
|
141
|
+
extend Benchmark::IPS # make ips/ips_quick available as module-level method
|
100
142
|
|
101
143
|
##
|
102
144
|
# :singleton-method: ips
|
metadata
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: benchmark-ips
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Phoenix
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
date: 2015-01-12 00:00:00.000000000 Z
|
@@ -53,6 +53,7 @@ files:
|
|
53
53
|
- README.md
|
54
54
|
- examples/advanced.rb
|
55
55
|
- examples/hold.rb
|
56
|
+
- examples/quick.rb
|
56
57
|
- examples/save.rb
|
57
58
|
- examples/simple.rb
|
58
59
|
- lib/benchmark/compare.rb
|
@@ -71,7 +72,7 @@ homepage: https://github.com/evanphx/benchmark-ips
|
|
71
72
|
licenses:
|
72
73
|
- MIT
|
73
74
|
metadata: {}
|
74
|
-
post_install_message:
|
75
|
+
post_install_message:
|
75
76
|
rdoc_options:
|
76
77
|
- "--main"
|
77
78
|
- README.md
|
@@ -88,8 +89,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
88
89
|
- !ruby/object:Gem::Version
|
89
90
|
version: '0'
|
90
91
|
requirements: []
|
91
|
-
rubygems_version: 3.3.
|
92
|
-
signing_key:
|
92
|
+
rubygems_version: 3.0.3.1
|
93
|
+
signing_key:
|
93
94
|
specification_version: 4
|
94
95
|
summary: A iterations per second enhancement to Benchmark.
|
95
96
|
test_files: []
|