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 +4 -4
- data/History.txt +11 -0
- data/Manifest.txt +0 -1
- data/README.md +24 -12
- data/lib/benchmark/compare.rb +34 -6
- data/lib/benchmark/ips.rb +41 -2
- data/lib/benchmark/ips/job.rb +98 -24
- data/lib/benchmark/ips/report.rb +90 -6
- data/lib/benchmark/timing.rb +16 -0
- data/test/test_benchmark_ips.rb +1 -1
- metadata +9 -10
- data/lib/benchmark/helpers.rb +0 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b0795c8f86b241fbf0e02d13401e209cac488ad
|
4
|
+
data.tar.gz: bd46b20f496f074e93c33a378da27e7ae225fe62
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f7d3b4ca509f2fcca1ec8f5eef9b0f2d0e2bc218abe7d69b359f9c41a64767dc19b16f8be1ee6bafd3c33d1f738ae0cc54fdbb12922d67cecd0092f885dc8c42
|
7
|
+
data.tar.gz: 3ca470bf622922c813cf8f6f6a82a4124b681d172cb1662488507a020ea314244ad012ee6ae724c81509135b8ce24539da4492dc8f0a7711c80b98f98974310d
|
data/History.txt
CHANGED
@@ -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!
|
data/Manifest.txt
CHANGED
data/README.md
CHANGED
@@ -1,12 +1,16 @@
|
|
1
|
-
[](http://badge.fury.io/rb/benchmark-ips)
|
2
|
+
[](http://travis-ci.org/evanphx/benchmark-ips)
|
3
|
+
[](http://inch-ci.org/github/evanphx/benchmark-ips)
|
2
4
|
|
3
5
|
# benchmark-ips
|
4
6
|
|
5
|
-
*
|
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
|
-
|
64
|
-
|
65
|
-
|
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
|
-
|
68
|
-
|
69
|
-
|
73
|
+
addition 4955278.9 (±8.7%) i/s - 24155106 in 5.002163s
|
74
|
+
addition2 24011974.8 (±9.5%) i/s - 114246912 in 4.995446s
|
75
|
+
addition3 23958619.8 (±9.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)
|
data/lib/benchmark/compare.rb
CHANGED
@@ -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
|
-
|
47
|
+
$stdout.puts "\nComparison:"
|
20
48
|
|
21
49
|
if iter
|
22
|
-
|
50
|
+
$stdout.printf "%20s: %10.1f i/s\n", best.label, best.ips
|
23
51
|
else
|
24
|
-
|
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
|
-
|
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
|
-
|
63
|
+
$stdout.puts "#{name.rjust(20)}: #{report.runtime}s - #{x}x slower"
|
36
64
|
end
|
37
65
|
end
|
38
66
|
|
39
|
-
|
67
|
+
$stdout.puts
|
40
68
|
end
|
41
69
|
end
|
42
70
|
|
data/lib/benchmark/ips.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/benchmark/ips/job.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
44
|
-
|
45
|
-
|
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
|
-
#
|
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
|
-
#
|
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
|
-
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
138
|
-
# before
|
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
|
-
#
|
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
|
-
|
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
|
-
#
|
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
|
data/lib/benchmark/ips/report.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
31
|
-
|
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
|
data/lib/benchmark/timing.rb
CHANGED
@@ -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
|
data/test/test_benchmark_ips.rb
CHANGED
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.
|
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-
|
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.
|
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.
|
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.
|
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.
|
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:
|
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
|
data/lib/benchmark/helpers.rb
DELETED
@@ -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
|