Skip to content

Commit 3cb5a6a

Browse files
committed
GODRIVER-3455 Make BSON benchmarks more representative of real use cases.
1 parent b225485 commit 3cb5a6a

File tree

1 file changed

+159
-54
lines changed

1 file changed

+159
-54
lines changed

bson/benchmark_test.go

Lines changed: 159 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,11 @@ func readExtJSONFile(filename string) map[string]interface{} {
182182
}
183183

184184
func BenchmarkMarshal(b *testing.B) {
185+
b.ReportAllocs()
186+
185187
cases := []struct {
186188
desc string
187-
value interface{}
189+
value any
188190
}{
189191
{
190192
desc: "simple struct",
@@ -194,6 +196,23 @@ func BenchmarkMarshal(b *testing.B) {
194196
desc: "nested struct",
195197
value: nestedInstance,
196198
},
199+
{
200+
desc: "simple D",
201+
value: D{
202+
{"field1String", "foo"},
203+
{"field1Int64", int64(1)},
204+
{"field1Float64", float64(3.0)},
205+
{"field2String", "bar"},
206+
{"field2Int64", int64(2)},
207+
{"field2Float64", float64(3.1)},
208+
{"field3String", "baz"},
209+
{"field3Int64", int64(3)},
210+
{"field3Float64", float64(3.14)},
211+
{"field4String", "qux"},
212+
{"field4Int64", int64(4)},
213+
{"field4Float64", float64(3.141)},
214+
},
215+
},
197216
{
198217
desc: "deep_bson.json.gz",
199218
value: readExtJSONFile("deep_bson.json.gz"),
@@ -208,119 +227,205 @@ func BenchmarkMarshal(b *testing.B) {
208227
},
209228
}
210229

211-
for _, tc := range cases {
212-
b.Run(tc.desc, func(b *testing.B) {
213-
b.Run("BSON", func(b *testing.B) {
214-
for i := 0; i < b.N; i++ {
215-
_, err := Marshal(tc.value)
216-
if err != nil {
217-
b.Errorf("error marshalling BSON: %s", err)
230+
b.Run("BSON", func(b *testing.B) {
231+
for _, tc := range cases {
232+
tc := tc // Capture range variable.
233+
234+
b.Run(tc.desc, func(b *testing.B) {
235+
b.RunParallel(func(pb *testing.PB) {
236+
for pb.Next() {
237+
_, err := Marshal(tc.value)
238+
if err != nil {
239+
b.Errorf("error marshalling BSON: %s", err)
240+
}
218241
}
219-
}
242+
})
220243
})
244+
}
245+
})
221246

222-
b.Run("extJSON", func(b *testing.B) {
223-
for i := 0; i < b.N; i++ {
224-
_, err := MarshalExtJSON(tc.value, true, false)
225-
if err != nil {
226-
b.Errorf("error marshalling extended JSON: %s", err)
247+
b.Run("extJSON", func(b *testing.B) {
248+
for _, tc := range cases {
249+
tc := tc // Capture range variable.
250+
251+
b.Run(tc.desc, func(b *testing.B) {
252+
b.RunParallel(func(pb *testing.PB) {
253+
for pb.Next() {
254+
_, err := MarshalExtJSON(tc.value, true, false)
255+
if err != nil {
256+
b.Errorf("error marshalling extended JSON: %s", err)
257+
}
227258
}
228-
}
259+
})
229260
})
261+
}
262+
})
230263

231-
b.Run("JSON", func(b *testing.B) {
232-
for i := 0; i < b.N; i++ {
233-
_, err := json.Marshal(tc.value)
234-
if err != nil {
235-
b.Errorf("error marshalling JSON: %s", err)
264+
b.Run("JSON", func(b *testing.B) {
265+
for _, tc := range cases {
266+
tc := tc // Capture range variable.
267+
268+
b.Run(tc.desc, func(b *testing.B) {
269+
b.RunParallel(func(pb *testing.PB) {
270+
for pb.Next() {
271+
_, err := json.Marshal(tc.value)
272+
if err != nil {
273+
b.Errorf("error marshalling JSON: %s", err)
274+
}
236275
}
237-
}
276+
})
238277
})
239-
})
240-
}
278+
}
279+
})
241280
}
242281

243282
func BenchmarkUnmarshal(b *testing.B) {
283+
b.ReportAllocs()
284+
244285
cases := []struct {
245286
desc string
246-
value interface{}
287+
value any
288+
dst func() any
247289
}{
248290
{
249-
desc: "simple struct",
291+
desc: "simple to struct",
250292
value: encodetestInstance,
293+
dst: func() any { return &encodetest{} },
251294
},
252295
{
253-
desc: "nested struct",
296+
desc: "simple to map",
297+
value: encodetestInstance,
298+
dst: func() any { return &map[string]any{} },
299+
},
300+
{
301+
desc: "simple to D",
302+
value: encodetestInstance,
303+
dst: func() any { return &D{} },
304+
},
305+
{
306+
desc: "nested to struct",
254307
value: nestedInstance,
308+
dst: func() any { return &encodetest{} },
255309
},
256310
{
257-
desc: "deep_bson.json.gz",
311+
desc: "nested to map",
312+
value: nestedInstance,
313+
dst: func() any { return &map[string]any{} },
314+
},
315+
{
316+
desc: "nested to D",
317+
value: nestedInstance,
318+
dst: func() any { return &D{} },
319+
},
320+
{
321+
desc: "deep_bson.json.gz to map",
258322
value: readExtJSONFile("deep_bson.json.gz"),
323+
dst: func() any { return &map[string]any{} },
259324
},
260325
{
261-
desc: "flat_bson.json.gz",
326+
desc: "deep_bson.json.gz to D",
327+
value: readExtJSONFile("deep_bson.json.gz"),
328+
dst: func() any { return &D{} },
329+
},
330+
{
331+
desc: "flat_bson.json.gz to map",
262332
value: readExtJSONFile("flat_bson.json.gz"),
333+
dst: func() any { return &map[string]any{} },
263334
},
264335
{
265-
desc: "full_bson.json.gz",
336+
desc: "flat_bson.json.gz to D",
337+
value: readExtJSONFile("flat_bson.json.gz"),
338+
dst: func() any { return &D{} },
339+
},
340+
{
341+
desc: "full_bson.json.gz to map",
266342
value: readExtJSONFile("full_bson.json.gz"),
343+
dst: func() any { return &map[string]any{} },
344+
},
345+
{
346+
desc: "full_bson.json.gz to D",
347+
value: readExtJSONFile("full_bson.json.gz"),
348+
dst: func() any { return &D{} },
267349
},
268350
}
269351

270-
for _, tc := range cases {
271-
b.Run(tc.desc, func(b *testing.B) {
272-
b.Run("BSON", func(b *testing.B) {
352+
b.Run("BSON", func(b *testing.B) {
353+
for _, tc := range cases {
354+
tc := tc // Capture range variable.
355+
356+
b.Run(tc.desc, func(b *testing.B) {
273357
data, err := Marshal(tc.value)
274358
if err != nil {
275359
b.Errorf("error marshalling BSON: %s", err)
276360
return
277361
}
278362

363+
b.SetBytes(int64(len(data)))
279364
b.ResetTimer()
280-
var v2 map[string]interface{}
281-
for i := 0; i < b.N; i++ {
282-
err := Unmarshal(data, &v2)
283-
if err != nil {
284-
b.Errorf("error unmarshalling BSON: %s", err)
365+
b.RunParallel(func(pb *testing.PB) {
366+
for pb.Next() {
367+
val := tc.dst()
368+
err := Unmarshal(data, val)
369+
if err != nil {
370+
b.Errorf("error unmarshalling BSON: %s", err)
371+
}
285372
}
286-
}
373+
})
287374
})
375+
}
376+
})
288377

289-
b.Run("extJSON", func(b *testing.B) {
378+
b.Run("extJSON", func(b *testing.B) {
379+
for _, tc := range cases {
380+
tc := tc // Capture range variable.
381+
382+
b.Run(tc.desc, func(b *testing.B) {
290383
data, err := MarshalExtJSON(tc.value, true, false)
291384
if err != nil {
292385
b.Errorf("error marshalling extended JSON: %s", err)
293386
return
294387
}
295388

389+
b.SetBytes(int64(len(data)))
296390
b.ResetTimer()
297-
var v2 map[string]interface{}
298-
for i := 0; i < b.N; i++ {
299-
err := UnmarshalExtJSON(data, true, &v2)
300-
if err != nil {
301-
b.Errorf("error unmarshalling extended JSON: %s", err)
391+
b.RunParallel(func(pb *testing.PB) {
392+
for pb.Next() {
393+
val := tc.dst()
394+
err := UnmarshalExtJSON(data, true, val)
395+
if err != nil {
396+
b.Errorf("error unmarshalling extended JSON: %s", err)
397+
}
302398
}
303-
}
399+
})
304400
})
401+
}
402+
})
305403

306-
b.Run("JSON", func(b *testing.B) {
404+
b.Run("JSON", func(b *testing.B) {
405+
for _, tc := range cases {
406+
tc := tc // Capture range variable.
407+
408+
b.Run(tc.desc, func(b *testing.B) {
307409
data, err := json.Marshal(tc.value)
308410
if err != nil {
309411
b.Errorf("error marshalling JSON: %s", err)
310412
return
311413
}
312414

415+
b.SetBytes(int64(len(data)))
313416
b.ResetTimer()
314-
var v2 map[string]interface{}
315-
for i := 0; i < b.N; i++ {
316-
err := json.Unmarshal(data, &v2)
317-
if err != nil {
318-
b.Errorf("error unmarshalling JSON: %s", err)
417+
b.RunParallel(func(pb *testing.PB) {
418+
for pb.Next() {
419+
val := tc.dst()
420+
err := json.Unmarshal(data, val)
421+
if err != nil {
422+
b.Errorf("error unmarshalling JSON: %s", err)
423+
}
319424
}
320-
}
425+
})
321426
})
322-
})
323-
}
427+
}
428+
})
324429
}
325430

326431
// The following benchmarks are copied from the Go standard library's

0 commit comments

Comments
 (0)