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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bc54b5cf0d24b23822486adf5759cceeefbef9a60c780454318472f4739050f6
4
- data.tar.gz: ea2764b060fef8c931c4636eb63e84d48f98242f7335648fed8b82b2fdeb053d
3
+ metadata.gz: aaebdee644671b1a757ded5e4868e1035718834832d2cfec8eb4460a3fa33171
4
+ data.tar.gz: a7349d06bb190b2ea9b7c06caf8da4ba26a48b00e550ca8a71ed1fe22ddff290
5
5
  SHA512:
6
- metadata.gz: 72ed2d83e42b125ca812aa1e79113be4726f8bb2e0ca4cb784dddc1d70eddc16c088308e1214cba9f7ec83ad77d89d9ae544b7892b6abac8f3e0b88d1617e7a8
7
- data.tar.gz: 94bda95d5db4a9032692e732a04eb3147ad3839b0e674f13d676b1fdf2130a8f0a269e6f5817791683965bf86662be10c7e5476e0539d71916b6b35562ac7806
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 documenation changes:
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(:time => 5, :warmup => 2)
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
- Calculating -------------------------------------
68
- addition 71.254k i/100ms
69
- addition2 68.658k i/100ms
70
- addition3 83.079k i/100ms
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
- 70.129k i/100ms
73
- -------------------------------------------------
74
- addition 4.955M (± 8.7%) i/s - 24.155M
75
- addition2 24.011M9.5%) i/s - 114.246M
76
- addition3 23.958M10.1%) i/s - 115.064M
69
+ 3.511M i/100ms
70
+ Calculating -------------------------------------
71
+ addition 36.209M2.8%) i/s (27.62 ns/i) - 182.253M in 5.037433s
72
+ addition2 36.552M7.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
- 5.014M9.1%) i/s - 24.545M
75
+ 36.164M5.8%) i/s (27.65 ns/i) - 181.312M in 5.038364s
79
76
 
80
77
  Comparison:
81
- addition2: 24011974.8 i/s
82
- addition3: 23958619.8 i/s - 1.00x slower
83
- addition-test-long-label: 5014756.0 i/s - 4.79x slower
84
- addition: 4955278.9 i/s - 4.85x slower
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
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'benchmark/ips'
4
+
5
+ def add
6
+ 1 + 1
7
+ end
8
+
9
+ def sub
10
+ 2 - 1
11
+ end
12
+
13
+ Benchmark.ips_quick(:add, :sub, warmup: 1, time: 1)
14
+
15
+ h = {}
16
+
17
+ Benchmark.ips_quick(:size, :empty?, on: h)
@@ -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, "Unknwon order: #{order.inspect}"
67
+ raise ArgumentError, "Unknown order: #{order.inspect}"
68
68
  end
69
69
 
70
70
  $stdout.puts "\nComparison:"
@@ -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 interations per second given the number
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.
@@ -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 supressed by default.
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.ljust(20) + (" - %s in %10.6fs" % [iters, runtime])
97
+ left + per_iter + (" - %s in %10.6fs" % [iters, runtime])
96
98
  else
97
- left.ljust(20) + (" - %s" % iters)
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.ljust(20) + (" - %10d in %10.6fs" % [@iterations, runtime])
105
+ left + per_iter + (" - %10d in %10.6fs" % [@iterations, runtime])
104
106
  else
105
- left.ljust(20) + (" - %10d" % @iterations)
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 repesentation of Entry object.
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
- # @see https://github.com/evanphx/benchmark-ips
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.13.0"
23
+ VERSION = "2.14.0"
21
24
 
22
25
  # CODENAME of current version.
23
- CODENAME = "Long Awaited"
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.13.0
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.7
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: []