benchmark-ips 2.0.0 → 2.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 21b099f60a4072356c1870798deab178dc6fe7f5
4
- data.tar.gz: 173c42ebe9730b48a3cf019b8f92c093066cd497
3
+ metadata.gz: 2b0795c8f86b241fbf0e02d13401e209cac488ad
4
+ data.tar.gz: bd46b20f496f074e93c33a378da27e7ae225fe62
5
5
  SHA512:
6
- metadata.gz: cd342a80b701d34c2034462a3ee765ac92ef809e2345fac3be3a05673fa34662c1db4ad618065eafd74c50078ab77081ccf3f70efdd63045efc4156a88dd88cb
7
- data.tar.gz: 09e2598b1fb76dde4abe095703d3ffea4f5f8dcd30b53492168e69b437d04ca59198d003da417637cc09beecc2f87d025754522fe30915e499606389865fe85a
6
+ metadata.gz: f7d3b4ca509f2fcca1ec8f5eef9b0f2d0e2bc218abe7d69b359f9c41a64767dc19b16f8be1ee6bafd3c33d1f738ae0cc54fdbb12922d67cecd0092f885dc8c42
7
+ data.tar.gz: 3ca470bf622922c813cf8f6f6a82a4124b681d172cb1662488507a020ea314244ad012ee6ae724c81509135b8ce24539da4492dc8f0a7711c80b98f98974310d
@@ -1,3 +1,14 @@
1
+ === 2.1.0 / 2014-11-10
2
+
3
+ * Documentation changes:
4
+ * Many documentation fixes by Juanito Fatas!
5
+ * Minor readme fix by Will Leinweber
6
+
7
+ * 2 minor features:
8
+ * Displaying the total runtime for a job is suppressed unless interesting
9
+ * Formatting of large values improved (human vs raw mode)
10
+ * Contributed by Charles Oliver Nutter
11
+
1
12
  === 2.0.0 / 2014-06-18
2
13
 
3
14
  * The 'Davy Stevenson' release!
@@ -4,7 +4,6 @@ Manifest.txt
4
4
  README.md
5
5
  Rakefile
6
6
  lib/benchmark/compare.rb
7
- lib/benchmark/helpers.rb
8
7
  lib/benchmark/ips.rb
9
8
  lib/benchmark/ips/report.rb
10
9
  lib/benchmark/ips/job.rb
data/README.md CHANGED
@@ -1,12 +1,16 @@
1
- [![Build Status](https://secure.travis-ci.org/evanphx/benchmark-ips.png)](http://travis-ci.org/evanphx/benchmark-ips)
1
+ [![Gem Version](https://badge.fury.io/rb/benchmark-ips.svg)](http://badge.fury.io/rb/benchmark-ips)
2
+ [![Build Status](https://secure.travis-ci.org/evanphx/benchmark-ips.svg)](http://travis-ci.org/evanphx/benchmark-ips)
3
+ [![Inline docs](http://inch-ci.org/github/evanphx/benchmark-ips.svg)](http://inch-ci.org/github/evanphx/benchmark-ips)
2
4
 
3
5
  # benchmark-ips
4
6
 
5
- * http://github.com/evanphx/benchmark-ips
7
+ * https://github.com/evanphx/benchmark-ips
8
+
9
+ * [documentation](http://rubydoc.info/gems/benchmark-ips)
6
10
 
7
11
  ## DESCRIPTION:
8
12
 
9
- A iterations per second enhancement to Benchmark
13
+ A iterations per second enhancement to Benchmark.
10
14
 
11
15
  ## FEATURES/PROBLEMS:
12
16
 
@@ -21,7 +25,7 @@ require 'benchmark/ips'
21
25
 
22
26
  Benchmark.ips do |x|
23
27
  # Configure the number of seconds used during
24
- # the warmup phase and calculation phase
28
+ # the warmup phase (default 2) and calculation phase (default 5)
25
29
  x.config(:time => 5, :warmup => 2)
26
30
 
27
31
  # These parameters can also be configured this way
@@ -60,13 +64,23 @@ This will generate the following report:
60
64
 
61
65
  ```
62
66
  Calculating -------------------------------------
63
- addition 147625 i/100ms
64
- addition2 151046 i/100ms
65
- addition3 172914 i/100ms
67
+ addition 71254 i/100ms
68
+ addition2 68658 i/100ms
69
+ addition3 83079 i/100ms
70
+ addition-test-long-label
71
+ 70129 i/100ms
66
72
  -------------------------------------------------
67
- addition 9247039.513.2%) i/s - 45320875 in 5.009003s
68
- addition2 26436533.8 (±22.1%) i/s - 124461904 in 4.994989s
69
- addition3 32227427.913.0%) i/s - 157524654 in 5.002928s
73
+ addition 4955278.98.7%) i/s - 24155106 in 5.002163s
74
+ addition2 24011974.8 (±9.5%) i/s - 114246912 in 4.995446s
75
+ addition3 23958619.89.9%) i/s - 115064415 in 4.996349s
76
+ addition-test-long-label
77
+ 5014756.0 (±9.1%) i/s - 24545150 in 5.009754s
78
+
79
+ Comparison:
80
+ addition2: 24011974.8 i/s
81
+ addition3: 23958619.8 i/s - 1.00x slower
82
+ addition-test-long-label: 5014756.0 i/s - 4.79x slower
83
+ addition: 4955278.9 i/s - 4.85x slower
70
84
  ```
71
85
 
72
86
  Benchmark/ips will report the number of iterations per second for a given block
@@ -96,8 +110,6 @@ After checking out the source, run:
96
110
  This task will install any missing dependencies, run the tests/specs,
97
111
  and generate the RDoc.
98
112
 
99
- Run the example file `bin/benchmark_ips` to test that everything is working properly.
100
-
101
113
  ## LICENSE:
102
114
 
103
115
  (The MIT License)
@@ -1,6 +1,34 @@
1
1
  module Benchmark
2
+ # Functionality of performaing comparison between reports.
3
+ #
4
+ # Usage:
5
+ #
6
+ # Add +x.compare!+ to perform comparison between reports.
7
+ #
8
+ # Example:
9
+ # > Benchmark.ips do |x|
10
+ # x.report('Reduce using tag') { [*1..10].reduce(:+) }
11
+ # x.report('Reduce using to_proc') { [*1..10].reduce(&:+) }
12
+ # x.compare!
13
+ # end
14
+ #
15
+ # Calculating -------------------------------------
16
+ # Reduce using tag 19216 i/100ms
17
+ # Reduce using to_proc 17437 i/100ms
18
+ # -------------------------------------------------
19
+ # Reduce using tag 278950.0 (±8.5%) i/s - 1402768 in 5.065112s
20
+ # Reduce using to_proc 247295.4 (±8.0%) i/s - 1238027 in 5.037299s
21
+ #
22
+ # Comparison:
23
+ # Reduce using tag: 278950.0 i/s
24
+ # Reduce using to_proc: 247295.4 i/s - 1.13x slower
25
+ #
26
+ # Besides regular Calculating report, this will also indicates which one is slower.
2
27
  module Compare
3
28
 
29
+ # Compare between reports, prints out facts of each report:
30
+ # runtime, comparative speed difference.
31
+ # @param reports [Array<Report>] Reports to compare.
4
32
  def compare(*reports)
5
33
  return if reports.size < 2
6
34
 
@@ -16,12 +44,12 @@ module Benchmark
16
44
 
17
45
  best = sorted.shift
18
46
 
19
- STDOUT.puts "\nComparison:"
47
+ $stdout.puts "\nComparison:"
20
48
 
21
49
  if iter
22
- STDOUT.printf "%20s: %10.1f i/s\n", best.label, best.ips
50
+ $stdout.printf "%20s: %10.1f i/s\n", best.label, best.ips
23
51
  else
24
- STDOUT.puts "#{best.rjust(20)}: #{best.runtime}s"
52
+ $stdout.puts "#{best.rjust(20)}: #{best.runtime}s"
25
53
  end
26
54
 
27
55
  sorted.each do |report|
@@ -29,14 +57,14 @@ module Benchmark
29
57
 
30
58
  if iter
31
59
  x = (best.ips.to_f / report.ips.to_f)
32
- STDOUT.printf "%20s: %10.1f i/s - %.2fx slower\n", name, report.ips, x
60
+ $stdout.printf "%20s: %10.1f i/s - %.2fx slower\n", name, report.ips, x
33
61
  else
34
62
  x = "%.2f" % (report.ips.to_f / best.ips.to_f)
35
- STDOUT.puts "#{name.rjust(20)}: #{report.runtime}s - #{x}x slower"
63
+ $stdout.puts "#{name.rjust(20)}: #{report.runtime}s - #{x}x slower"
36
64
  end
37
65
  end
38
66
 
39
- STDOUT.puts
67
+ $stdout.puts
40
68
  end
41
69
  end
42
70
 
@@ -4,11 +4,23 @@ require 'benchmark/compare'
4
4
  require 'benchmark/ips/report'
5
5
  require 'benchmark/ips/job'
6
6
 
7
+ # Performance benchmarking library
7
8
  module Benchmark
9
+ # Benchmark in iterations per second, no more guessing!
10
+ # @see https://github.com/evanphx/benchmark-ips
8
11
  module IPS
9
- VERSION = "2.0.0"
12
+
13
+ # Benchmark-ips Gem version.
14
+ VERSION = "2.1.0"
15
+
16
+ # CODENAME of current version.
10
17
  CODENAME = "Springtime Hummingbird Dance"
11
18
 
19
+ # Measure code in block, each code's benchmarked result will display in
20
+ # iteration per second with standard deviation in given time.
21
+ # @param time [Integer] Specify how long should benchmark your code in seconds.
22
+ # @param warmup [Integer] Specify how long should Warmup time run in seconds.
23
+ # @return [Report]
12
24
  def ips(time=nil, warmup=nil)
13
25
  suite = nil
14
26
 
@@ -48,7 +60,34 @@ module Benchmark
48
60
 
49
61
  return job.full_report
50
62
  end
63
+
64
+ # Set options for running the benchmarks.
65
+ # :format => [:human, :raw]
66
+ # :human format narrows precision and scales results for readability
67
+ # :raw format displays 6 places of precision and exact iteration counts
68
+ def self.options
69
+ @options ||= {:format => :human}
70
+ end
71
+
72
+ module Helpers
73
+ def scale(value)
74
+ scale = (Math.log10(value) / 3).to_i
75
+ suffix = case scale
76
+ when 1; 'k'
77
+ when 2; 'M'
78
+ when 3; 'B'
79
+ when 4; 'T'
80
+ when 5; 'Q'
81
+ else
82
+ # < 1000 or > 10^15, no scale or suffix
83
+ scale = 0
84
+ ' '
85
+ end
86
+ "%10.3f#{suffix}" % (value.to_f / (1000 ** scale))
87
+ end
88
+ module_function :scale
89
+ end
51
90
  end
52
91
 
53
- extend Benchmark::IPS
92
+ extend Benchmark::IPS # make ips available as module-level method
54
93
  end
@@ -1,11 +1,21 @@
1
1
  module Benchmark
2
2
  module IPS
3
+ # Benchmark jobs.
3
4
  class Job
4
-
5
+ # Microseconds per 100 millisecond.
5
6
  MICROSECONDS_PER_100MS = 100_000
7
+ # Microseconds per second.
6
8
  MICROSECONDS_PER_SECOND = 1_000_000
9
+ # The percentage of the expected runtime to allow
10
+ # before reporting a weird runtime
11
+ MAX_TIME_SKEW = 0.05
7
12
 
13
+ # Entries in Benchmark Jobs.
8
14
  class Entry
15
+ # Instantiate the Benchmark::IPS::Job::Entry.
16
+ # @param label [String] Label of Benchmarked code.
17
+ # @param action [String, Proc] Code to be benchmarked.
18
+ # @raise [ArgumentError] Raises when action is not String or not responding to +call+.
9
19
  def initialize(label, action)
10
20
  @label = label
11
21
 
@@ -30,8 +40,17 @@ module Benchmark
30
40
  end
31
41
  end
32
42
 
33
- attr_reader :label, :action
43
+ # The label of benchmarking action.
44
+ # @return [String] Label of action.
45
+ attr_reader :label
46
+
47
+ # The benchmarking action.
48
+ # @return [String, Proc] Code to be called, could be String / Proc.
49
+ attr_reader :action
34
50
 
51
+ # Add padding to label's right if label's length < 20,
52
+ # Otherwise add a new line and 20 whitespaces.
53
+ # @return [String] Right justified label.
35
54
  def label_rjust
36
55
  if @label.size > 20
37
56
  "#{@label}\n#{' ' * 20}"
@@ -40,10 +59,9 @@ module Benchmark
40
59
  end
41
60
  end
42
61
 
43
- def as_action?
44
- @as_action
45
- end
46
-
62
+ # Call action by given times, return if +@call_loop+ is present.
63
+ # @param times [Integer] Times to call +@action+.
64
+ # @return [Integer] Number of times the +@action+ has been called.
47
65
  def call_times(times)
48
66
  return @action.call(times) if @call_loop
49
67
 
@@ -56,6 +74,9 @@ module Benchmark
56
74
  end
57
75
  end
58
76
 
77
+ # Compile code into +call_times+ method.
78
+ # @param str [String] Code to be compiled.
79
+ # @return [Symbol] :call_times.
59
80
  def compile(str)
60
81
  m = (class << self; self; end)
61
82
  code = <<-CODE
@@ -69,20 +90,37 @@ module Benchmark
69
90
  CODE
70
91
  m.class_eval code
71
92
  end
72
- end
93
+ end # End of Entry
94
+
95
+ # class Job
73
96
 
74
- # An array of 2-element arrays, consisting of label and block pairs.
97
+ # Two-element arrays, consisting of label and block pairs.
98
+ # @return [Array<Entry>] list of entries
75
99
  attr_reader :list
76
100
 
77
- # Boolean determining whether to run comparison utility
101
+ # Determining whether to run comparison utility.
102
+ # @return [Boolean] true if needs to run compare.
78
103
  attr_reader :compare
79
104
 
80
- # Report object containing information about the run
105
+ # Report object containing information about the run.
106
+ # @return [Report] the report object.
81
107
  attr_reader :full_report
82
108
 
83
- attr_accessor :warmup, :time
109
+ # Storing Iterations in time period.
110
+ # @return [Hash]
84
111
  attr_reader :timing
85
112
 
113
+ # Warmup time setter and getter (in seconds).
114
+ # @return [Integer]
115
+ attr_accessor :warmup
116
+
117
+ # Calculation time setter and getter (in seconds).
118
+ # @return [Integer]
119
+ attr_accessor :time
120
+
121
+ # Instantiate the Benchmark::IPS::Job.
122
+ # @option opts [Benchmark::Suite] (nil) :suite Specify Benchmark::Suite.
123
+ # @option opts [Boolean] (false) :quiet Suppress the printing of information.
86
124
  def initialize opts={}
87
125
  @suite = opts[:suite] || nil
88
126
  @quiet = opts[:quiet] || false
@@ -92,27 +130,36 @@ module Benchmark
92
130
  @timing = {}
93
131
  @full_report = Report.new
94
132
 
95
- # defaults
133
+ # Default warmup and calculation time in seconds.
96
134
  @warmup = 2
97
135
  @time = 5
98
136
  end
99
137
 
138
+ # Job configuration options, set +@warmup+ and +@time+.
139
+ # @option opts [Integer] :warmup Warmup time.
140
+ # @option opts [Integer] :time Calculation time.
100
141
  def config opts
101
142
  @warmup = opts[:warmup] if opts[:warmup]
102
143
  @time = opts[:time] if opts[:time]
103
144
  end
104
145
 
146
+ # Return true if job needs to be compared.
147
+ # @return [Boolean] Need to compare?
105
148
  def compare?
106
149
  @compare
107
150
  end
108
151
 
152
+ # Set @compare to true.
109
153
  def compare!
110
154
  @compare = true
111
155
  end
112
156
 
113
- #
114
157
  # Registers the given label and block pair in the job list.
115
- #
158
+ # @param label [String] Label of benchmarked code.
159
+ # @param str [String] Code to be benchamrked.
160
+ # @param blk [Proc] Code to be benchamrked.
161
+ # @raise [ArgumentError] Raises if str and blk are both present.
162
+ # @raise [ArgumentError] Raises if str and blk are both absent.
116
163
  def item(label="", str=nil, &blk) # :yield:
117
164
  if blk and str
118
165
  raise ArgumentError, "specify a block and a str, but not both"
@@ -126,26 +173,35 @@ module Benchmark
126
173
  end
127
174
  alias_method :report, :item
128
175
 
129
- # calculate the cycles needed to run for approx 100ms
130
- # given the number of iterations to run the given time
176
+ # Calculate the cycles needed to run for approx 100ms,
177
+ # given the number of iterations to run the given time.
178
+ # @param [Float] time_msec Each iteration's time in ms.
179
+ # @param [Integer] iters Iterations.
180
+ # @return [Integer] Cycles per 100ms.
131
181
  def cycles_per_100ms time_msec, iters
132
182
  cycles = ((MICROSECONDS_PER_100MS / time_msec) * iters).to_i
133
183
  cycles = 1 if cycles <= 0
134
184
  cycles
135
185
  end
136
186
 
137
- # calculate the difference in microseconds between
138
- # before and after
187
+ # Calculate the time difference of before and after in microseconds.
188
+ # @param [Time] before time.
189
+ # @param [Time] after time.
190
+ # @return [Float] Time difference of before and after.
139
191
  def time_us before, after
140
192
  (after.to_f - before.to_f) * MICROSECONDS_PER_SECOND
141
193
  end
142
194
 
143
- # calculate the interations per second given the number
144
- # of cycles run and the time in microseconds that elapsed
195
+ # Calculate the interations per second given the number
196
+ # of cycles run and the time in microseconds that elapsed.
197
+ # @param [Integer] cycles Cycles.
198
+ # @param [Integer] time_us Time in microsecond.
199
+ # @return [Float] Iteration per second.
145
200
  def iterations_per_sec cycles, time_us
146
201
  MICROSECONDS_PER_SECOND * (cycles.to_f / time_us.to_f)
147
202
  end
148
203
 
204
+ # Run warmup.
149
205
  def run_warmup
150
206
  @list.each do |item|
151
207
  @suite.warming item.label, @warmup if @suite
@@ -172,12 +228,18 @@ module Benchmark
172
228
 
173
229
  @timing[item] = cycles_per_100ms warmup_time_us, warmup_iter
174
230
 
175
- $stdout.printf "%10d i/100ms\n", @timing[item] unless @quiet
231
+ case Benchmark::IPS.options[:format]
232
+ when :human
233
+ $stdout.printf "%s i/100ms\n", Helpers.scale(@timing[item]) unless @quiet
234
+ else
235
+ $stdout.printf "%10d i/100ms\n", @timing[item] unless @quiet
236
+ end
176
237
 
177
238
  @suite.warmup_stats warmup_time_us, @timing[item] if @suite
178
239
  end
179
240
  end
180
241
 
242
+ # Run calculation.
181
243
  def run
182
244
  @list.each do |item|
183
245
  @suite.running item.label, @time if @suite
@@ -194,7 +256,7 @@ module Benchmark
194
256
 
195
257
  measurements_us = []
196
258
 
197
- # running this number of cycles should take around 100ms
259
+ # Running this number of cycles should take around 100ms.
198
260
  cycles = @timing[item]
199
261
 
200
262
  while Time.now < target
@@ -204,7 +266,6 @@ module Benchmark
204
266
 
205
267
  # If for some reason the timing said this took no time (O_o)
206
268
  # then ignore the iteration entirely and start another.
207
- #
208
269
  iter_us = time_us before, after
209
270
  next if iter_us <= 0.0
210
271
 
@@ -213,6 +274,8 @@ module Benchmark
213
274
  measurements_us << iter_us
214
275
  end
215
276
 
277
+ final_time = Time.now
278
+
216
279
  measured_us = measurements_us.inject(0) { |a,i| a + i }
217
280
 
218
281
  all_ips = measurements_us.map { |time_us|
@@ -224,20 +287,31 @@ module Benchmark
224
287
 
225
288
  rep = create_report(item, measured_us, iter, avg_ips, sd_ips, cycles)
226
289
 
290
+ if (final_time - target).abs >= (@time.to_f * MAX_TIME_SKEW)
291
+ rep.show_total_time!
292
+ end
293
+
227
294
  $stdout.puts " #{rep.body}" unless @quiet
228
295
 
229
296
  @suite.add_report rep, caller(1).first if @suite
230
297
  end
231
298
  end
232
299
 
300
+ # Run comparison of entries in +@full_report+.
233
301
  def run_comparison
234
302
  @full_report.run_comparison
235
303
  end
236
304
 
305
+ # Create report by add entry to +@full_report+.
306
+ # @param item [Benchmark::IPS::Job::Entry] Report item.
307
+ # @param measured_us [Integer] Measured time in microsecond.
308
+ # @param iter [Integer] Iterations.
309
+ # @param avg_ips [Float] Average iterations per second.
310
+ # @param sd_ips [Float] Standard deviation iterations per second.
311
+ # @param cycles [Integer] Number of Cycles.
237
312
  def create_report(item, measured_us, iter, avg_ips, sd_ips, cycles)
238
313
  @full_report.add_entry item.label, measured_us, iter, avg_ips, sd_ips, cycles
239
314
  end
240
-
241
315
  end
242
316
  end
243
317
  end
@@ -1,10 +1,21 @@
1
1
  # encoding: utf-8
2
+
2
3
  module Benchmark
3
4
  module IPS
5
+
6
+ # Report contains benchamrking entries.
7
+ # Perform operations like add new entry, run comparison between entries.
4
8
  class Report
5
9
 
10
+ # Represents benchmarking code data for Report.
6
11
  class Entry
7
-
12
+ # Instantiate the Benchmark::IPS::Report::Entry.
13
+ # @param [String] label Label of entry.
14
+ # @param [Integer] us Measured time in microsecond.
15
+ # @param [Integer] iters Iterations.
16
+ # @param [Float] ips Iterations per second.
17
+ # @param [Float] ips_sd Standard deviation of iterations per second.
18
+ # @param [Integer] cycles Number of Cycles.
8
19
  def initialize(label, us, iters, ips, ips_sd, cycles)
9
20
  @label = label
10
21
  @microseconds = us
@@ -12,53 +23,126 @@ module Benchmark
12
23
  @ips = ips
13
24
  @ips_sd = ips_sd
14
25
  @measurement_cycle = cycles
26
+ @show_total_time = false
15
27
  end
16
28
 
17
- attr_reader :label, :microseconds, :iterations, :ips, :ips_sd, :measurement_cycle
29
+ # Label of entry.
30
+ # @return [String] the label of entry.
31
+ attr_reader :label
32
+
33
+ # Measured time in microsecond.
34
+ # @return [Integer] number of microseconds.
35
+ attr_reader :microseconds
36
+
37
+ # Number of Iterations.
38
+ # @return [Integer] number of iterations.
39
+ attr_reader :iterations
40
+
41
+ # Iterations per second.
42
+ # @return [Float] number of iterations per second.
43
+ attr_reader :ips
44
+
45
+ # Standard deviation of iteration per second.
46
+ # @return [Float] standard deviation of iteration per second.
47
+ attr_reader :ips_sd
48
+
49
+ # Number of Cycles.
50
+ # @return [Integer] number of cycles.
51
+ attr_reader :measurement_cycle
18
52
 
53
+ # Control if the total time the job took is reported.
54
+ # Typically this value is not significant because it's very
55
+ # close to the expected time, so it's supressed by default.
56
+ def show_total_time!
57
+ @show_total_time = true
58
+ end
59
+
60
+ # Return entry's microseconds in seconds.
61
+ # @return [Float] +@microseconds+ in seconds.
19
62
  def seconds
20
63
  @microseconds.to_f / 1_000_000.0
21
64
  end
22
65
 
66
+ # Return entry's standard deviation of iteration per second in percentage.
67
+ # @return [Float] +@ips_sd+ in percentage.
23
68
  def stddev_percentage
24
69
  100.0 * (@ips_sd.to_f / @ips.to_f)
25
70
  end
26
71
 
27
72
  alias_method :runtime, :seconds
28
73
 
74
+ # Return Entry body text with left padding.
75
+ # Body text contains information of iteration per second with
76
+ # percentage of standard deviation, iterations in runtime.
77
+ # @return [String] Left justified body.
29
78
  def body
30
- left = "%10.1f (±%.1f%%) i/s" % [ips, stddev_percentage]
31
- left.ljust(20) + (" - %10d in %10.6fs" % [@iterations, runtime])
79
+ case Benchmark::IPS.options[:format]
80
+ when :human
81
+ left = "%s (±%4.1f%%) i/s" % [Helpers.scale(ips), stddev_percentage]
82
+ iters = Helpers.scale(@iterations)
83
+
84
+ if @show_total_time
85
+ left.ljust(20) + (" - %s in %10.6fs" % [iters, runtime])
86
+ else
87
+ left.ljust(20) + (" - %s" % iters)
88
+ end
89
+ else
90
+ left = "%10.1f (±%.1f%%) i/s" % [ips, stddev_percentage]
91
+
92
+ if @show_total_time
93
+ left.ljust(20) + (" - %10d in %10.6fs" % [@iterations, runtime])
94
+ else
95
+ left.ljust(20) + (" - %10d" % @iterations)
96
+ end
97
+ end
32
98
  end
33
99
 
100
+ # Return header with padding if +@label+ is < length of 20.
101
+ # @return [String] Right justified header (+@label+).
34
102
  def header
35
103
  @label.rjust(20)
36
104
  end
37
105
 
106
+ # Return string repesentation of Entry object.
107
+ # @return [String] Header and body.
38
108
  def to_s
39
109
  "#{header} #{body}"
40
110
  end
41
111
 
112
+ # Print entry to current standard output ($stdout).
42
113
  def display
43
114
  $stdout.puts to_s
44
115
  end
45
- end
116
+ end # End of Entry
117
+
118
+ # class Report
46
119
 
120
+ # Entry to represent each benchamarked code in Report.
121
+ # @return [Array<Entry>] Entries in Report.
47
122
  attr_reader :entries
48
123
 
124
+ # Instantiate the Report.
49
125
  def initialize
50
126
  @entries = []
51
127
  end
52
128
 
129
+ # Add entry to report.
130
+ # @param label [String] Entry label.
131
+ # @param microseconds [Integer] Measured time in microsecond.
132
+ # @param iters [Integer] Iterations.
133
+ # @param ips [Float] Average Iterations per second.
134
+ # @param ips_sd [Float] Standard deviation of iterations per second.
135
+ # @param measurement_cycle [Integer] Number of cycles.
136
+ # @return [Entry] Last added entry.
53
137
  def add_entry label, microseconds, iters, ips, ips_sd, measurement_cycle
54
138
  @entries << Entry.new(label, microseconds, iters, ips, ips_sd, measurement_cycle)
55
139
  @entries.last
56
140
  end
57
141
 
142
+ # Run comparison of entries.
58
143
  def run_comparison
59
144
  Benchmark.compare(*@entries)
60
145
  end
61
-
62
146
  end
63
147
  end
64
148
  end
@@ -1,10 +1,18 @@
1
1
  module Benchmark
2
+ # Perform caclulations on Timing results.
2
3
  module Timing
4
+
5
+ # Calculate (arithmetic) mean of given samples.
6
+ # @param [Array] samples Samples to calculate mean.
7
+ # @return [Float] Mean of given samples.
3
8
  def self.mean(samples)
4
9
  sum = samples.inject(0) { |acc, i| acc + i }
5
10
  sum / samples.size
6
11
  end
7
12
 
13
+ # Calculate variance of given samples.
14
+ # @param [Float] m Optional mean (Expected value).
15
+ # @return [Float] Variance of given samples.
8
16
  def self.variance(samples, m=nil)
9
17
  m ||= mean(samples)
10
18
 
@@ -13,10 +21,17 @@ module Benchmark
13
21
  total / samples.size
14
22
  end
15
23
 
24
+ # Calculate standard deviation of given samples.
25
+ # @param [Array] samples Samples to calculate standard deviation.
26
+ # @param [Float] m Optional mean (Expected value).
27
+ # @return [Float] standard deviation of given samples.
16
28
  def self.stddev(samples, m=nil)
17
29
  Math.sqrt variance(samples, m)
18
30
  end
19
31
 
32
+ # Resample mean of given samples.
33
+ # @param [Integer] resample_times Resample times, defaults to 100.
34
+ # @return [Array] Resampled samples.
20
35
  def self.resample_mean(samples, resample_times=100)
21
36
  resamples = []
22
37
 
@@ -28,6 +43,7 @@ module Benchmark
28
43
  resamples
29
44
  end
30
45
 
46
+ # Recycle unsed objects by starting Garbage Collector.
31
47
  def self.clean_env
32
48
  # rbx
33
49
  if GC.respond_to? :run
@@ -28,7 +28,7 @@ class TestBenchmarkIPS < Minitest::Test
28
28
  assert_in_delta 4.0, rep1.ips, 0.2
29
29
 
30
30
  assert_equal "sleep 0.05", rep2.label
31
- assert_equal 20, rep2.iterations
31
+ assert_in_delta 20.0, rep2.iterations.to_f, 1.0
32
32
  assert_in_delta 20.0, rep2.ips, 1.0
33
33
  end
34
34
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: benchmark-ips
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Phoenix
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-18 00:00:00.000000000 Z
11
+ date: 2014-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '5.3'
19
+ version: '5.4'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '5.3'
26
+ version: '5.4'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rdoc
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,15 +44,15 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '3.12'
47
+ version: '3.13'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '3.12'
55
- description: A iterations per second enhancement to Benchmark
54
+ version: '3.13'
55
+ description: A iterations per second enhancement to Benchmark.
56
56
  email:
57
57
  - evan@phx.io
58
58
  executables: []
@@ -69,13 +69,12 @@ files:
69
69
  - README.md
70
70
  - Rakefile
71
71
  - lib/benchmark/compare.rb
72
- - lib/benchmark/helpers.rb
73
72
  - lib/benchmark/ips.rb
74
73
  - lib/benchmark/ips/job.rb
75
74
  - lib/benchmark/ips/report.rb
76
75
  - lib/benchmark/timing.rb
77
76
  - test/test_benchmark_ips.rb
78
- homepage: http://github.com/evanphx/benchmark-ips
77
+ homepage: https://github.com/evanphx/benchmark-ips
79
78
  licenses:
80
79
  - MIT
81
80
  metadata: {}
@@ -100,6 +99,6 @@ rubyforge_project:
100
99
  rubygems_version: 2.2.2
101
100
  signing_key:
102
101
  specification_version: 4
103
- summary: A iterations per second enhancement to Benchmark
102
+ summary: A iterations per second enhancement to Benchmark.
104
103
  test_files:
105
104
  - test/test_benchmark_ips.rb
@@ -1,46 +0,0 @@
1
- module Benchmark
2
- module Helpers
3
-
4
- def fixnum_max
5
- if Object.const_defined?(:RUBY_ENGINE)
6
- case RUBY_ENGINE
7
- when "ruby"
8
- 2 ** (wordsize - 2) - 1
9
- when "rbx"
10
- Fixnum::MAX
11
- when "jruby"
12
- 9223372036854775807
13
- else
14
- raise "Maximum Fixnum size now known yet for #{RUBY_ENGINE}"
15
- end
16
- else
17
- 2 ** (wordsize - 2) - 1
18
- end
19
- end
20
- module_function :fixnum_max
21
-
22
- def fixnum_min
23
- if Object.const_defined?(:RUBY_ENGINE)
24
- case RUBY_ENGINE
25
- when "ruby"
26
- - 2 ** (wordsize - 2)
27
- when "rbx"
28
- Fixnum::MIN
29
- when "jruby"
30
- -9223372036854775808
31
- else
32
- raise "Minimum Fixnum size now known yet for #{RUBY_ENGINE}"
33
- end
34
- else
35
- - 2 ** (wordsize - 2)
36
- end
37
- end
38
- module_function :fixnum_min
39
-
40
- def wordsize
41
- 8 * 1.size
42
- end
43
- module_function :wordsize
44
-
45
- end
46
- end