1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
require 'minitest/spec'
require 'benchmark'
MiniTest::Unit.autorun
describe Benchmark do
BENCH_FOR_TIMES_UPTO = lambda do |x|
n = 1000
tf = x.report("for:") { for _ in 1..n; '1'; end }
tt = x.report("times:") { n.times do ; '1'; end }
tu = x.report("upto:") { 1.upto(n) do ; '1'; end }
[tf+tt+tu, (tf+tt+tu)/3]
end
BENCH_FOR_TIMES_UPTO_NO_LABEL = lambda do |x|
n = 1000
x.report { for _ in 1..n; '1'; end }
x.report { n.times do ; '1'; end }
x.report { 1.upto(n) do ; '1'; end }
end
LABELS = %w[first second third]
def bench(type = :bm, *args, &block)
if block
Benchmark.send(type, *args, &block)
else
Benchmark.send(type, *args) do |x|
LABELS.each { |label|
x.report(label) {}
}
end
end
end
def capture_output
capture_io { yield }.first.gsub(/[ \-]\d\.\d{6}/, ' --time--')
end
def capture_bench_output(type, *args, &block)
capture_output { bench(type, *args, &block) }
end
describe 'Tms' do
it 'outputs nicely' do
Benchmark::Tms.new.to_s.must_equal " 0.000000 0.000000 0.000000 ( 0.000000)\n"
Benchmark::Tms.new(1,2,3,4,5).to_s.must_equal " 1.000000 2.000000 10.000000 ( 5.000000)\n"
Benchmark::Tms.new(1,2,3,4,5,'label').format('%u %y %U %Y %t %r %n').must_equal \
"1.000000 2.000000 3.000000 4.000000 10.000000 (5.000000) label"
Benchmark::Tms.new(1).format('%u %.3f', 2).must_equal "1.000000 2.000"
Benchmark::Tms.new(100, 150, 0, 0, 200).to_s.must_equal \
"100.000000 150.000000 250.000000 (200.000000)\n"
end
it 'wont modify the format String given' do
format = "format %u"
Benchmark::Tms.new.format(format)
format.must_equal "format %u"
end
end
describe 'benchmark' do
it 'makes extra calcultations with an Array at the end of the benchmark and show the result' do
capture_bench_output(:benchmark,
Benchmark::CAPTION, 7,
Benchmark::FORMAT, ">total:", ">avg:",
&BENCH_FOR_TIMES_UPTO).must_equal BENCHMARK_OUTPUT_WITH_TOTAL_AVG
end
end
describe 'bm' do
it "returns an Array of the times with the labels" do
[:bm, :bmbm].each do |meth|
capture_io do
results = bench(meth)
results.must_be_instance_of Array
results.size.must_equal LABELS.size
results.zip(LABELS).each { |tms, label|
tms.must_be_instance_of Benchmark::Tms
tms.label.must_equal label
}
end
end
end
it 'correctly output when the label width is given' do
capture_bench_output(:bm, 6).must_equal BM_OUTPUT
end
it 'correctly output when no label is given' do
capture_bench_output(:bm, &BENCH_FOR_TIMES_UPTO_NO_LABEL).must_equal BM_OUTPUT_NO_LABEL
end
it 'can make extra calcultations with an array at the end of the benchmark' do
capture_bench_output(:bm, 7, ">total:", ">avg:",
&BENCH_FOR_TIMES_UPTO).must_equal BENCHMARK_OUTPUT_WITH_TOTAL_AVG
end
end
describe 'bmbm' do
it 'correctly guess the label width even when not given' do
capture_bench_output(:bmbm).must_equal BMBM_OUTPUT
end
it 'correctly output when the label width is given (bmbm ignore it, but it is a frequent mistake)' do
capture_bench_output(:bmbm, 6).must_equal BMBM_OUTPUT
end
end
describe 'Report' do
describe '#item' do
it 'shows the title, even if not a string' do
capture_bench_output(:bm) { |x| x.report(:title) {} }.must_include 'title'
capture_bench_output(:bmbm) { |x| x.report(:title) {} }.must_include 'title'
end
end
end
describe 'Bugs' do
it '[ruby-dev:40906] can add in-place the time of execution of the block given' do
t = Benchmark::Tms.new
t.real.must_equal 0
t.add! { sleep 0.1 }
t.real.wont_equal 0
end
end
end
BM_OUTPUT = <<BENCH
user system total real
first --time-- --time-- --time-- ( --time--)
second --time-- --time-- --time-- ( --time--)
third --time-- --time-- --time-- ( --time--)
BENCH
BM_OUTPUT_NO_LABEL = <<BENCH
user system total real
--time-- --time-- --time-- ( --time--)
--time-- --time-- --time-- ( --time--)
--time-- --time-- --time-- ( --time--)
BENCH
BMBM_OUTPUT = <<BENCH
Rehearsal ------------------------------------------
first --time-- --time-- --time-- ( --time--)
second --time-- --time-- --time-- ( --time--)
third --time-- --time-- --time-- ( --time--)
--------------------------------- total: --time--sec
user system total real
first --time-- --time-- --time-- ( --time--)
second --time-- --time-- --time-- ( --time--)
third --time-- --time-- --time-- ( --time--)
BENCH
BENCHMARK_OUTPUT_WITH_TOTAL_AVG = <<BENCH
user system total real
for: --time-- --time-- --time-- ( --time--)
times: --time-- --time-- --time-- ( --time--)
upto: --time-- --time-- --time-- ( --time--)
>total: --time-- --time-- --time-- ( --time--)
>avg: --time-- --time-- --time-- ( --time--)
BENCH
|