Source file
src/testing/benchmark_test.go
1
2
3
4
5 package testing_test
6
7 import (
8 "bytes"
9 "cmp"
10 "runtime"
11 "slices"
12 "strings"
13 "sync/atomic"
14 "testing"
15 "text/template"
16 "time"
17 )
18
19 var prettyPrintTests = []struct {
20 v float64
21 expected string
22 }{
23 {0, " 0 x"},
24 {1234.1, " 1234 x"},
25 {-1234.1, " -1234 x"},
26 {999.950001, " 1000 x"},
27 {999.949999, " 999.9 x"},
28 {99.9950001, " 100.0 x"},
29 {99.9949999, " 99.99 x"},
30 {-99.9949999, " -99.99 x"},
31 {0.000999950001, " 0.001000 x"},
32 {0.000999949999, " 0.0009999 x"},
33 {0.0000999949999, " 0.0001000 x"},
34 }
35
36 func TestPrettyPrint(t *testing.T) {
37 for _, tt := range prettyPrintTests {
38 buf := new(strings.Builder)
39 testing.PrettyPrint(buf, tt.v, "x")
40 if tt.expected != buf.String() {
41 t.Errorf("prettyPrint(%v): expected %q, actual %q", tt.v, tt.expected, buf.String())
42 }
43 }
44 }
45
46 func TestResultString(t *testing.T) {
47
48 r := testing.BenchmarkResult{
49 N: 100,
50 T: 240 * time.Nanosecond,
51 }
52 if r.NsPerOp() != 2 {
53 t.Errorf("NsPerOp: expected 2, actual %v", r.NsPerOp())
54 }
55 if want, got := " 100\t 2.400 ns/op", r.String(); want != got {
56 t.Errorf("String: expected %q, actual %q", want, got)
57 }
58
59
60 r.T = 40 * time.Nanosecond
61 if want, got := " 100\t 0.4000 ns/op", r.String(); want != got {
62 t.Errorf("String: expected %q, actual %q", want, got)
63 }
64
65
66 r.T = 0
67 if want, got := " 100", r.String(); want != got {
68 t.Errorf("String: expected %q, actual %q", want, got)
69 }
70 }
71
72 func TestRunParallel(t *testing.T) {
73 if testing.Short() {
74 t.Skip("skipping in short mode")
75 }
76 testing.Benchmark(func(b *testing.B) {
77 procs := uint32(0)
78 iters := uint64(0)
79 b.SetParallelism(3)
80 b.RunParallel(func(pb *testing.PB) {
81 atomic.AddUint32(&procs, 1)
82 for pb.Next() {
83 atomic.AddUint64(&iters, 1)
84 }
85 })
86 if want := uint32(3 * runtime.GOMAXPROCS(0)); procs != want {
87 t.Errorf("got %v procs, want %v", procs, want)
88 }
89 if iters != uint64(b.N) {
90 t.Errorf("got %v iters, want %v", iters, b.N)
91 }
92 })
93 }
94
95 func TestRunParallelFail(t *testing.T) {
96 testing.Benchmark(func(b *testing.B) {
97 b.RunParallel(func(pb *testing.PB) {
98
99
100 b.Log("log")
101 b.Error("error")
102 })
103 })
104 }
105
106 func TestRunParallelFatal(t *testing.T) {
107 testing.Benchmark(func(b *testing.B) {
108 b.RunParallel(func(pb *testing.PB) {
109 for pb.Next() {
110 if b.N > 1 {
111 b.Fatal("error")
112 }
113 }
114 })
115 })
116 }
117
118 func TestRunParallelSkipNow(t *testing.T) {
119 testing.Benchmark(func(b *testing.B) {
120 b.RunParallel(func(pb *testing.PB) {
121 for pb.Next() {
122 if b.N > 1 {
123 b.SkipNow()
124 }
125 }
126 })
127 })
128 }
129
130 func TestLoopEqualsRangeOverBN(t *testing.T) {
131
132 var nIterated, nInfered int
133 testing.Benchmark(func(b *testing.B) {
134 i := 0
135 for b.Loop() {
136 i++
137 }
138 nIterated = i
139 nInfered = b.N
140 })
141 if nIterated != nInfered {
142 t.Fatalf("Iteration of the two different benchmark loop flavor differs, got %d iterations want %d", nIterated, nInfered)
143 }
144 }
145
146 func ExampleB_RunParallel() {
147
148 testing.Benchmark(func(b *testing.B) {
149 templ := template.Must(template.New("test").Parse("Hello, {{.}}!"))
150
151
152 b.RunParallel(func(pb *testing.PB) {
153
154 var buf bytes.Buffer
155 for pb.Next() {
156
157 buf.Reset()
158 templ.Execute(&buf, "World")
159 }
160 })
161 })
162 }
163
164 func TestReportMetric(t *testing.T) {
165 res := testing.Benchmark(func(b *testing.B) {
166 b.ReportMetric(12345, "ns/op")
167 b.ReportMetric(0.2, "frobs/op")
168 })
169
170 if res.NsPerOp() != 12345 {
171 t.Errorf("NsPerOp: expected %v, actual %v", 12345, res.NsPerOp())
172 }
173
174 res.N = 1
175 want := " 1\t 12345 ns/op\t 0.2000 frobs/op"
176 if want != res.String() {
177 t.Errorf("expected %q, actual %q", want, res.String())
178 }
179 }
180
181 func ExampleB_ReportMetric() {
182
183
184 testing.Benchmark(func(b *testing.B) {
185 var compares int64
186 for i := 0; i < b.N; i++ {
187 s := []int{5, 4, 3, 2, 1}
188 slices.SortFunc(s, func(a, b int) int {
189 compares++
190 return cmp.Compare(a, b)
191 })
192 }
193
194
195 b.ReportMetric(float64(compares)/float64(b.N), "compares/op")
196
197
198 b.ReportMetric(float64(compares)/float64(b.Elapsed().Nanoseconds()), "compares/ns")
199 })
200 }
201
202 func ExampleB_ReportMetric_parallel() {
203
204
205 testing.Benchmark(func(b *testing.B) {
206 var compares atomic.Int64
207 b.RunParallel(func(pb *testing.PB) {
208 for pb.Next() {
209 s := []int{5, 4, 3, 2, 1}
210 slices.SortFunc(s, func(a, b int) int {
211
212
213
214 compares.Add(1)
215 return cmp.Compare(a, b)
216 })
217 }
218 })
219
220
221
222
223
224
225 b.ReportMetric(float64(compares.Load())/float64(b.N), "compares/op")
226
227
228 b.ReportMetric(float64(compares.Load())/float64(b.Elapsed().Nanoseconds()), "compares/ns")
229 })
230 }
231
View as plain text