benchmark-ips 2.11.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 +17 -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 +67 -0
- data/lib/benchmark/ips/job/{stdout_report.rb → stream_report.rb} +11 -9
- data/lib/benchmark/ips/job.rb +23 -24
- 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 +54 -18
- data/lib/benchmark/timing.rb +1 -1
- metadata +8 -8
- data/lib/benchmark/ips/job/noop_report.rb +0 -27
- data/lib/benchmark/ips/noop_suite.rb +0 -25
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,19 @@
|
|
|
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
|
+
|
|
12
|
+
### 2.12.0 / 2023-03-08
|
|
13
|
+
|
|
14
|
+
* Feature
|
|
15
|
+
* Adds MultiReport and ability report to a stream rather than a string.
|
|
16
|
+
|
|
1
17
|
### 2.11.0 / 2023-02-15
|
|
2
18
|
|
|
3
19
|
* Feature
|
|
@@ -182,7 +198,7 @@ Add missing files
|
|
|
182
198
|
* 1 minor fix:
|
|
183
199
|
* Don't send label through printf so that % work directly
|
|
184
200
|
|
|
185
|
-
* 1
|
|
201
|
+
* 1 documentation changes:
|
|
186
202
|
* Use HEREDOC and wrap at 80 chars for example result description
|
|
187
203
|
|
|
188
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
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
module Benchmark
|
|
2
|
+
module IPS
|
|
3
|
+
class Job
|
|
4
|
+
class MultiReport
|
|
5
|
+
# @returns out [Array<StreamReport>] list of reports to send output
|
|
6
|
+
attr_accessor :out
|
|
7
|
+
|
|
8
|
+
def empty?
|
|
9
|
+
@out.empty?
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def quiet?
|
|
13
|
+
@out.none? { |rpt| rpt.kind_of?(StreamReport) }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def quiet!
|
|
17
|
+
@out.delete_if { |rpt| rpt.kind_of?(StreamReport) }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @param report [StreamReport] report to accept input?
|
|
21
|
+
def <<(report)
|
|
22
|
+
if report.kind_of?(MultiReport)
|
|
23
|
+
self << report.out
|
|
24
|
+
elsif report.kind_of?(Enumerable)
|
|
25
|
+
@out += report
|
|
26
|
+
elsif report
|
|
27
|
+
@out << report
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @param out [Array<StreamReport>] list of reports to send output
|
|
32
|
+
def initialize(out = nil)
|
|
33
|
+
@out = []
|
|
34
|
+
self << out
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def start_warming
|
|
38
|
+
@out.each { |o| o.start_warming if o.respond_to?(:start_warming) }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def warming(label, warmup)
|
|
42
|
+
@out.each { |o| o.warming(label, warmup) }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def warmup_stats(warmup_time_us, timing)
|
|
46
|
+
@out.each { |o| o.warmup_stats(warmup_time_us, timing) }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def start_running
|
|
50
|
+
@out.each { |o| o.start_running if o.respond_to?(:start_running) }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def running(label, warmup)
|
|
54
|
+
@out.each { |o| o.running(label, warmup) }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def add_report(item, caller)
|
|
58
|
+
@out.each { |o| o.add_report(item, caller) }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def footer
|
|
62
|
+
@out.each { |o| o.footer if o.respond_to?(:footer) }
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -1,43 +1,45 @@
|
|
|
1
1
|
module Benchmark
|
|
2
2
|
module IPS
|
|
3
3
|
class Job
|
|
4
|
-
class
|
|
5
|
-
def initialize
|
|
4
|
+
class StreamReport
|
|
5
|
+
def initialize(stream = $stdout)
|
|
6
6
|
@last_item = nil
|
|
7
|
+
@out = stream
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
def start_warming
|
|
10
|
-
|
|
11
|
+
@out.puts RUBY_DESCRIPTION
|
|
12
|
+
@out.puts "Warming up --------------------------------------"
|
|
11
13
|
end
|
|
12
14
|
|
|
13
15
|
def start_running
|
|
14
|
-
|
|
16
|
+
@out.puts "Calculating -------------------------------------"
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
def warming(label, _warmup)
|
|
18
|
-
|
|
20
|
+
@out.print rjust(label)
|
|
19
21
|
end
|
|
20
22
|
|
|
21
23
|
def warmup_stats(_warmup_time_us, timing)
|
|
22
24
|
case format
|
|
23
25
|
when :human
|
|
24
|
-
|
|
26
|
+
@out.printf "%s i/100ms\n", Helpers.scale(timing)
|
|
25
27
|
else
|
|
26
|
-
|
|
28
|
+
@out.printf "%10d i/100ms\n", timing
|
|
27
29
|
end
|
|
28
30
|
end
|
|
29
31
|
|
|
30
32
|
alias_method :running, :warming
|
|
31
33
|
|
|
32
34
|
def add_report(item, caller)
|
|
33
|
-
|
|
35
|
+
@out.puts " #{item.body}"
|
|
34
36
|
@last_item = item
|
|
35
37
|
end
|
|
36
38
|
|
|
37
39
|
def footer
|
|
38
40
|
return unless @last_item
|
|
39
41
|
footer = @last_item.stats.footer
|
|
40
|
-
|
|
42
|
+
@out.puts footer.rjust(40) if footer
|
|
41
43
|
end
|
|
42
44
|
|
|
43
45
|
private
|
data/lib/benchmark/ips/job.rb
CHANGED
|
@@ -53,11 +53,15 @@ module Benchmark
|
|
|
53
53
|
|
|
54
54
|
# Silence output
|
|
55
55
|
# @return [Boolean]
|
|
56
|
-
|
|
56
|
+
def quiet
|
|
57
|
+
@out.quiet?
|
|
58
|
+
end
|
|
57
59
|
|
|
58
60
|
# Suite
|
|
59
|
-
# @return [Benchmark::IPS::
|
|
60
|
-
|
|
61
|
+
# @return [Benchmark::IPS::MultiReport]
|
|
62
|
+
def suite
|
|
63
|
+
@out
|
|
64
|
+
end
|
|
61
65
|
|
|
62
66
|
# Instantiate the Benchmark::IPS::Job.
|
|
63
67
|
def initialize opts={}
|
|
@@ -81,7 +85,7 @@ module Benchmark
|
|
|
81
85
|
@stats = :sd
|
|
82
86
|
@confidence = 95
|
|
83
87
|
|
|
84
|
-
|
|
88
|
+
@out = MultiReport.new(StreamReport.new)
|
|
85
89
|
end
|
|
86
90
|
|
|
87
91
|
# Job configuration options, set +@warmup+ and +@time+.
|
|
@@ -91,24 +95,23 @@ module Benchmark
|
|
|
91
95
|
def config opts
|
|
92
96
|
@warmup = opts[:warmup] if opts[:warmup]
|
|
93
97
|
@time = opts[:time] if opts[:time]
|
|
94
|
-
@suite = opts[:suite] if opts[:suite]
|
|
95
98
|
@iterations = opts[:iterations] if opts[:iterations]
|
|
96
99
|
@stats = opts[:stats] if opts[:stats]
|
|
97
100
|
@confidence = opts[:confidence] if opts[:confidence]
|
|
98
101
|
self.quiet = opts[:quiet] if opts.key?(:quiet)
|
|
99
|
-
self.suite = opts[:suite]
|
|
102
|
+
self.suite = opts[:suite] if opts[:suite]
|
|
100
103
|
end
|
|
101
104
|
|
|
102
105
|
def quiet=(val)
|
|
103
|
-
|
|
106
|
+
if val # remove instances of StreamReport
|
|
107
|
+
@out.quiet!
|
|
108
|
+
else # ensure there is an instance of StreamReport
|
|
109
|
+
@out << StreamReport.new if @out.quiet?
|
|
110
|
+
end
|
|
104
111
|
end
|
|
105
112
|
|
|
106
113
|
def suite=(suite)
|
|
107
|
-
@
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
def reporter(quiet:)
|
|
111
|
-
quiet ? NoopReport.new : StdoutReport.new
|
|
114
|
+
@out << suite
|
|
112
115
|
end
|
|
113
116
|
|
|
114
117
|
# Return true if job needs to be compared.
|
|
@@ -200,7 +203,7 @@ module Benchmark
|
|
|
200
203
|
(after.to_f - before.to_f) * MICROSECONDS_PER_SECOND
|
|
201
204
|
end
|
|
202
205
|
|
|
203
|
-
# Calculate the
|
|
206
|
+
# Calculate the iterations per second given the number
|
|
204
207
|
# of cycles run and the time in microseconds that elapsed.
|
|
205
208
|
# @param [Integer] cycles Cycles.
|
|
206
209
|
# @param [Integer] time_us Time in microsecond.
|
|
@@ -245,19 +248,19 @@ module Benchmark
|
|
|
245
248
|
|
|
246
249
|
def run
|
|
247
250
|
if @warmup && @warmup != 0 then
|
|
248
|
-
@
|
|
251
|
+
@out.start_warming
|
|
249
252
|
@iterations.times do
|
|
250
253
|
run_warmup
|
|
251
254
|
end
|
|
252
255
|
end
|
|
253
256
|
|
|
254
|
-
@
|
|
257
|
+
@out.start_running
|
|
255
258
|
|
|
256
259
|
@iterations.times do |n|
|
|
257
260
|
run_benchmark
|
|
258
261
|
end
|
|
259
262
|
|
|
260
|
-
@
|
|
263
|
+
@out.footer
|
|
261
264
|
end
|
|
262
265
|
|
|
263
266
|
# Run warmup.
|
|
@@ -265,8 +268,7 @@ module Benchmark
|
|
|
265
268
|
@list.each do |item|
|
|
266
269
|
next if run_single? && @held_results && @held_results.key?(item.label)
|
|
267
270
|
|
|
268
|
-
@
|
|
269
|
-
@stdout.warming item.label, @warmup
|
|
271
|
+
@out.warming item.label, @warmup
|
|
270
272
|
|
|
271
273
|
Timing.clean_env
|
|
272
274
|
|
|
@@ -300,8 +302,7 @@ module Benchmark
|
|
|
300
302
|
item.call_times cycles
|
|
301
303
|
end
|
|
302
304
|
|
|
303
|
-
@
|
|
304
|
-
@suite.warmup_stats warmup_time_us, @timing[item]
|
|
305
|
+
@out.warmup_stats warmup_time_us, @timing[item]
|
|
305
306
|
|
|
306
307
|
break if run_single?
|
|
307
308
|
end
|
|
@@ -312,8 +313,7 @@ module Benchmark
|
|
|
312
313
|
@list.each do |item|
|
|
313
314
|
next if run_single? && @held_results && @held_results.key?(item.label)
|
|
314
315
|
|
|
315
|
-
@
|
|
316
|
-
@stdout.running item.label, @time
|
|
316
|
+
@out.running item.label, @time
|
|
317
317
|
|
|
318
318
|
Timing.clean_env
|
|
319
319
|
|
|
@@ -355,8 +355,7 @@ module Benchmark
|
|
|
355
355
|
rep.show_total_time!
|
|
356
356
|
end
|
|
357
357
|
|
|
358
|
-
@
|
|
359
|
-
@suite.add_report rep, caller(1).first
|
|
358
|
+
@out.add_report rep, caller(1).first
|
|
360
359
|
|
|
361
360
|
break if run_single?
|
|
362
361
|
end
|
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
|
@@ -5,23 +5,25 @@ require 'benchmark/ips/stats/stats_metric'
|
|
|
5
5
|
require 'benchmark/ips/stats/sd'
|
|
6
6
|
require 'benchmark/ips/stats/bootstrap'
|
|
7
7
|
require 'benchmark/ips/report'
|
|
8
|
-
require 'benchmark/ips/noop_suite'
|
|
9
8
|
require 'benchmark/ips/job/entry'
|
|
10
|
-
require 'benchmark/ips/job/
|
|
11
|
-
require 'benchmark/ips/job/
|
|
9
|
+
require 'benchmark/ips/job/stream_report'
|
|
10
|
+
require 'benchmark/ips/job/multi_report'
|
|
12
11
|
require 'benchmark/ips/job'
|
|
13
12
|
|
|
14
13
|
# Performance benchmarking library
|
|
15
14
|
module Benchmark
|
|
16
15
|
# Benchmark in iterations per second, no more guessing!
|
|
17
|
-
#
|
|
16
|
+
#
|
|
17
|
+
# See Benchmark.ips for documentation on using this gem~
|
|
18
|
+
#
|
|
19
|
+
# @see {https://github.com/evanphx/benchmark-ips}
|
|
18
20
|
module IPS
|
|
19
21
|
|
|
20
22
|
# Benchmark-ips Gem version.
|
|
21
|
-
VERSION = "2.
|
|
23
|
+
VERSION = "2.14.0"
|
|
22
24
|
|
|
23
25
|
# CODENAME of current version.
|
|
24
|
-
CODENAME = "
|
|
26
|
+
CODENAME = "Akagi"
|
|
25
27
|
|
|
26
28
|
# Measure code in block, each code's benchmarked result will display in
|
|
27
29
|
# iteration per second with standard deviation in given time.
|
|
@@ -74,6 +76,32 @@ module Benchmark
|
|
|
74
76
|
report
|
|
75
77
|
end
|
|
76
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
|
+
|
|
77
105
|
# Set options for running the benchmarks.
|
|
78
106
|
# :format => [:human, :raw]
|
|
79
107
|
# :human format narrows precision and scales results for readability
|
|
@@ -83,26 +111,34 @@ module Benchmark
|
|
|
83
111
|
end
|
|
84
112
|
|
|
85
113
|
module Helpers
|
|
114
|
+
SUFFIXES = ['', 'k', 'M', 'B', 'T', 'Q'].freeze
|
|
115
|
+
|
|
86
116
|
def scale(value)
|
|
87
117
|
scale = (Math.log10(value) / 3).to_i
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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)
|
|
94
133
|
else
|
|
95
|
-
|
|
96
|
-
scale = 0
|
|
97
|
-
' '
|
|
134
|
+
"%.2f s" % (duration_ns / 1_000_000_000)
|
|
98
135
|
end
|
|
99
|
-
"%10.3f#{suffix}" % (value.to_f / (1000 ** scale))
|
|
100
136
|
end
|
|
101
|
-
module_function :
|
|
137
|
+
module_function :humanize_duration
|
|
102
138
|
end
|
|
103
139
|
end
|
|
104
140
|
|
|
105
|
-
extend Benchmark::IPS # make ips available as module-level method
|
|
141
|
+
extend Benchmark::IPS # make ips/ips_quick available as module-level method
|
|
106
142
|
|
|
107
143
|
##
|
|
108
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,15 +53,15 @@ 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
|
|
59
60
|
- lib/benchmark/ips.rb
|
|
60
61
|
- lib/benchmark/ips/job.rb
|
|
61
62
|
- lib/benchmark/ips/job/entry.rb
|
|
62
|
-
- lib/benchmark/ips/job/
|
|
63
|
-
- lib/benchmark/ips/job/
|
|
64
|
-
- lib/benchmark/ips/noop_suite.rb
|
|
63
|
+
- lib/benchmark/ips/job/multi_report.rb
|
|
64
|
+
- lib/benchmark/ips/job/stream_report.rb
|
|
65
65
|
- lib/benchmark/ips/report.rb
|
|
66
66
|
- lib/benchmark/ips/share.rb
|
|
67
67
|
- lib/benchmark/ips/stats/bootstrap.rb
|
|
@@ -72,7 +72,7 @@ homepage: https://github.com/evanphx/benchmark-ips
|
|
|
72
72
|
licenses:
|
|
73
73
|
- MIT
|
|
74
74
|
metadata: {}
|
|
75
|
-
post_install_message:
|
|
75
|
+
post_install_message:
|
|
76
76
|
rdoc_options:
|
|
77
77
|
- "--main"
|
|
78
78
|
- README.md
|
|
@@ -89,8 +89,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
89
89
|
- !ruby/object:Gem::Version
|
|
90
90
|
version: '0'
|
|
91
91
|
requirements: []
|
|
92
|
-
rubygems_version: 3.3.
|
|
93
|
-
signing_key:
|
|
92
|
+
rubygems_version: 3.0.3.1
|
|
93
|
+
signing_key:
|
|
94
94
|
specification_version: 4
|
|
95
95
|
summary: A iterations per second enhancement to Benchmark.
|
|
96
96
|
test_files: []
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
module Benchmark
|
|
2
|
-
module IPS
|
|
3
|
-
class Job
|
|
4
|
-
class NoopReport
|
|
5
|
-
def start_warming
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def start_running
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def footer
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def warming(a, b)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def warmup_stats(a, b)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def add_report(a, b)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
alias_method :running, :warming
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
module Benchmark
|
|
2
|
-
module IPS
|
|
3
|
-
class NoopSuite
|
|
4
|
-
def start_warming
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
def start_running
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def footer
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def warming(a, b)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def warmup_stats(a, b)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def add_report(a, b)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
alias_method :running, :warming
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|