benchmark-ips 2.12.0 → 2.14.0
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/History.md +12 -1
- data/LICENSE +0 -0
- data/README.md +29 -20
- data/examples/advanced.rb +0 -0
- data/examples/hold.rb +0 -0
- data/examples/quick.rb +17 -0
- data/examples/save.rb +0 -0
- data/lib/benchmark/compare.rb +1 -1
- data/lib/benchmark/ips/job/entry.rb +0 -0
- data/lib/benchmark/ips/job/multi_report.rb +0 -0
- data/lib/benchmark/ips/job/stream_report.rb +1 -0
- data/lib/benchmark/ips/job.rb +1 -1
- data/lib/benchmark/ips/report.rb +10 -8
- data/lib/benchmark/ips/share.rb +0 -0
- data/lib/benchmark/ips/stats/bootstrap.rb +0 -0
- data/lib/benchmark/ips/stats/sd.rb +0 -0
- data/lib/benchmark/ips/stats/stats_metric.rb +0 -0
- data/lib/benchmark/ips.rb +52 -15
- data/lib/benchmark/timing.rb +1 -1
- 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/LICENSE
CHANGED
File without changes
|
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/advanced.rb
CHANGED
File without changes
|
data/examples/hold.rb
CHANGED
File without changes
|
data/examples/quick.rb
ADDED
data/examples/save.rb
CHANGED
File without changes
|
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:"
|
File without changes
|
File without changes
|
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/share.rb
CHANGED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
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
|
@@ -82,26 +111,34 @@ module Benchmark
|
|
82
111
|
end
|
83
112
|
|
84
113
|
module Helpers
|
114
|
+
SUFFIXES = ['', 'k', 'M', 'B', 'T', 'Q'].freeze
|
115
|
+
|
85
116
|
def scale(value)
|
86
117
|
scale = (Math.log10(value) / 3).to_i
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
118
|
+
scale = 0 if scale < 0 || scale >= SUFFIXES.size
|
119
|
+
suffix = SUFFIXES[scale]
|
120
|
+
scaled_value = value.to_f / (1000 ** scale)
|
121
|
+
|
122
|
+
"%10.3f#{suffix}" % scaled_value
|
123
|
+
end
|
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)
|
93
133
|
else
|
94
|
-
|
95
|
-
scale = 0
|
96
|
-
' '
|
134
|
+
"%.2f s" % (duration_ns / 1_000_000_000)
|
97
135
|
end
|
98
|
-
"%10.3f#{suffix}" % (value.to_f / (1000 ** scale))
|
99
136
|
end
|
100
|
-
module_function :
|
137
|
+
module_function :humanize_duration
|
101
138
|
end
|
102
139
|
end
|
103
140
|
|
104
|
-
extend Benchmark::IPS # make ips available as module-level method
|
141
|
+
extend Benchmark::IPS # make ips/ips_quick available as module-level method
|
105
142
|
|
106
143
|
##
|
107
144
|
# :singleton-method: ips
|
data/lib/benchmark/timing.rb
CHANGED
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: []
|