benchmark-ips 2.0.0 → 2.1.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
  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