benchmark-ips 2.10.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 +22 -1
- data/LICENSE +0 -0
- data/README.md +52 -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 +17 -11
- data/lib/benchmark/ips/share.rb +0 -0
- data/lib/benchmark/ips/stats/bootstrap.rb +0 -0
- data/lib/benchmark/ips/stats/sd.rb +2 -2
- 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,24 @@
|
|
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
|
+
|
17
|
+
### 2.11.0 / 2023-02-15
|
18
|
+
|
19
|
+
* Feature
|
20
|
+
* Adds .json! method to the ips block argument, allowing you to print the output as JSON to a file or STDOUT.
|
21
|
+
|
1
22
|
### 2.10.0 / 2022-02-17
|
2
23
|
|
3
24
|
* Feature
|
@@ -177,7 +198,7 @@ Add missing files
|
|
177
198
|
* 1 minor fix:
|
178
199
|
* Don't send label through printf so that % work directly
|
179
200
|
|
180
|
-
* 1
|
201
|
+
* 1 documentation changes:
|
181
202
|
* Use HEREDOC and wrap at 80 chars for example result description
|
182
203
|
|
183
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:
|
@@ -237,6 +246,29 @@ Benchmark.ips do |x|
|
|
237
246
|
end
|
238
247
|
```
|
239
248
|
|
249
|
+
### Output as JSON
|
250
|
+
|
251
|
+
You can generate output in JSON. If you want to write JSON to a file, pass filename to `json!` method:
|
252
|
+
|
253
|
+
```ruby
|
254
|
+
Benchmark.ips do |x|
|
255
|
+
x.report("some report") { }
|
256
|
+
x.json! 'filename.json'
|
257
|
+
end
|
258
|
+
```
|
259
|
+
|
260
|
+
If you want to write JSON to STDOUT, pass `STDOUT` to `json!` method and set `quiet = true` before `json!`:
|
261
|
+
|
262
|
+
```ruby
|
263
|
+
Benchmark.ips do |x|
|
264
|
+
x.report("some report") { }
|
265
|
+
x.quiet = true
|
266
|
+
x.json! STDOUT
|
267
|
+
end
|
268
|
+
```
|
269
|
+
|
270
|
+
This is useful when the output from `benchmark-ips` becomes an input of other tools via stdin.
|
271
|
+
|
240
272
|
## REQUIREMENTS:
|
241
273
|
|
242
274
|
* None!
|
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}"
|
@@ -183,9 +185,13 @@ module Benchmark
|
|
183
185
|
# Generate json from Report#data to given path.
|
184
186
|
# @param path [String] path to generate json.
|
185
187
|
def generate_json(path)
|
186
|
-
|
187
|
-
|
188
|
-
|
188
|
+
require "json"
|
189
|
+
if path.respond_to?(:write) # STDOUT
|
190
|
+
path.write JSON.pretty_generate(data)
|
191
|
+
else
|
192
|
+
File.open path, "w" do |f|
|
193
|
+
f.write JSON.pretty_generate(data)
|
194
|
+
end
|
189
195
|
end
|
190
196
|
end
|
191
197
|
end
|
data/lib/benchmark/ips/share.rb
CHANGED
File without changes
|
File without changes
|
@@ -24,9 +24,9 @@ module Benchmark
|
|
24
24
|
# @returns [Array<Float, nil>] the slowdown and the error (not calculated for standard deviation)
|
25
25
|
def slowdown(baseline)
|
26
26
|
if baseline.central_tendency > central_tendency
|
27
|
-
[baseline.central_tendency.to_f / central_tendency,
|
27
|
+
[baseline.central_tendency.to_f / central_tendency, nil]
|
28
28
|
else
|
29
|
-
[central_tendency.to_f / baseline.central_tendency,
|
29
|
+
[central_tendency.to_f / baseline.central_tendency, nil]
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
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.
|
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
|