Skip to content

Commit 3eb8bce

Browse files
casperisfinebyroot
andauthored
compare!(order: :baseline) option (#123)
When enabled the first report is considered the baseline against which other reports are compared. ``` Comparison: Reduce using block: 886202.5 i/s Reduce using tag: 1821055.0 i/s - 2.05x (± 0.00) faster Reduce using to_proc: 895948.1 i/s - same-ish: difference falls within error ``` Instead of: ``` Comparison: Reduce using tag: 1826997.4 i/s Reduce using to_proc: 881011.9 i/s - 2.07x (± 0.00) slower Reduce using block: 879261.1 i/s - 2.08x (± 0.00) slower ``` Co-authored-by: Jean Boussier <[email protected]>
1 parent cc71098 commit 3eb8bce

File tree

5 files changed

+58
-12
lines changed

5 files changed

+58
-12
lines changed

lib/benchmark/compare.rb

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,31 +26,67 @@ module Benchmark
2626
# Reduce using to_proc: 247295.4 i/s - 1.13x slower
2727
#
2828
# 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.
2951
module Compare
3052

3153
# Compare between reports, prints out facts of each report:
3254
# runtime, comparative speed difference.
3355
# @param entries [Array<Report::Entry>] Reports to compare.
34-
def compare(*entries)
56+
def compare(*entries, order: :fastest)
3557
return if entries.size < 2
3658

37-
sorted = entries.sort_by{ |e| e.stats.central_tendency }.reverse
38-
39-
best = sorted.shift
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}"
68+
end
4069

4170
$stdout.puts "\nComparison:"
4271

43-
$stdout.printf "%20s: %10.1f i/s\n", best.label.to_s, best.stats.central_tendency
72+
$stdout.printf "%20s: %10.1f i/s\n", baseline.label.to_s, baseline.stats.central_tendency
4473

4574
sorted.each do |report|
4675
name = report.label.to_s
4776

4877
$stdout.printf "%20s: %10.1f i/s - ", name, report.stats.central_tendency
4978

50-
if report.stats.overlaps?(best.stats)
79+
if report.stats.overlaps?(baseline.stats)
5180
$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"
5288
else
53-
slowdown, error = report.stats.slowdown(best.stats)
89+
slowdown, error = report.stats.slowdown(baseline.stats)
5490
$stdout.printf "%.2fx ", slowdown
5591
if error
5692
$stdout.printf " (± %.2f)", error
@@ -61,7 +97,7 @@ def compare(*entries)
6197
$stdout.puts
6298
end
6399

64-
footer = best.stats.footer
100+
footer = baseline.stats.footer
65101
$stdout.puts footer.rjust(40) if footer
66102

67103
$stdout.puts

lib/benchmark/ips/job.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ def initialize opts={}
6565
@run_single = false
6666
@json_path = false
6767
@compare = false
68+
@compare_order = :fastest
6869
@held_path = nil
6970
@held_results = nil
7071

@@ -117,8 +118,9 @@ def compare?
117118
end
118119

119120
# Run comparison utility.
120-
def compare!
121+
def compare!(order: :fastest)
121122
@compare = true
123+
@compare_order = order
122124
end
123125

124126
# Return true if results are held while multiple Ruby invocations
@@ -373,7 +375,7 @@ def create_stats(samples)
373375

374376
# Run comparison of entries in +@full_report+.
375377
def run_comparison
376-
@full_report.run_comparison if compare?
378+
@full_report.run_comparison(@compare_order) if compare?
377379
end
378380

379381
# Generate json from +@full_report+.

lib/benchmark/ips/report.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,8 @@ def data
176176
end
177177

178178
# Run comparison of entries.
179-
def run_comparison
180-
Benchmark.compare(*@entries)
179+
def run_comparison(order)
180+
Benchmark.compare(*@entries, order: order)
181181
end
182182

183183
# Generate json from Report#data to given path.

lib/benchmark/ips/stats/bootstrap.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ def slowdown(baseline)
3333
[slowdown, error]
3434
end
3535

36+
def speedup(baseline)
37+
baseline.slowdown(self)
38+
end
39+
3640
def footer
3741
"with #{(@confidence.to_f * 100).round(1)}% confidence"
3842
end

lib/benchmark/ips/stats/sd.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ def slowdown(baseline)
3030
end
3131
end
3232

33+
def speedup(baseline)
34+
baseline.slowdown(self)
35+
end
36+
3337
def footer
3438
nil
3539
end

0 commit comments

Comments
 (0)