@@ -19,6 +19,20 @@ import (
19
19
"testing"
20
20
)
21
21
22
+ var encodetestBsonD D
23
+
24
+ func init () {
25
+ b , err := Marshal (encodetestInstance )
26
+ if err != nil {
27
+ panic (fmt .Sprintf ("error marshling struct: %v" , err ))
28
+ }
29
+
30
+ err = Unmarshal (b , & encodetestBsonD )
31
+ if err != nil {
32
+ panic (fmt .Sprintf ("error unmarshaling BSON: %v" , err ))
33
+ }
34
+ }
35
+
22
36
type encodetest struct {
23
37
Field1String string
24
38
Field1Int64 int64
@@ -184,7 +198,7 @@ func readExtJSONFile(filename string) map[string]interface{} {
184
198
func BenchmarkMarshal (b * testing.B ) {
185
199
cases := []struct {
186
200
desc string
187
- value interface {}
201
+ value any
188
202
}{
189
203
{
190
204
desc : "simple struct" ,
@@ -194,6 +208,10 @@ func BenchmarkMarshal(b *testing.B) {
194
208
desc : "nested struct" ,
195
209
value : nestedInstance ,
196
210
},
211
+ {
212
+ desc : "simple D" ,
213
+ value : encodetestBsonD ,
214
+ },
197
215
{
198
216
desc : "deep_bson.json.gz" ,
199
217
value : readExtJSONFile ("deep_bson.json.gz" ),
@@ -208,119 +226,211 @@ func BenchmarkMarshal(b *testing.B) {
208
226
},
209
227
}
210
228
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 )
229
+ b .Run ("BSON" , func (b * testing.B ) {
230
+ for _ , tc := range cases {
231
+ tc := tc // Capture range variable.
232
+
233
+ b .Run (tc .desc , func (b * testing.B ) {
234
+ b .ReportAllocs ()
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
+ }
218
241
}
219
- }
242
+ })
220
243
})
244
+ }
245
+ })
221
246
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 .ReportAllocs ()
253
+ b .RunParallel (func (pb * testing.PB ) {
254
+ for pb .Next () {
255
+ _ , err := MarshalExtJSON (tc .value , true , false )
256
+ if err != nil {
257
+ b .Errorf ("error marshalling extended JSON: %s" , err )
258
+ }
227
259
}
228
- }
260
+ })
229
261
})
262
+ }
263
+ })
230
264
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 )
265
+ b .Run ("JSON" , func (b * testing.B ) {
266
+ for _ , tc := range cases {
267
+ tc := tc // Capture range variable.
268
+
269
+ b .Run (tc .desc , func (b * testing.B ) {
270
+ b .ReportAllocs ()
271
+ b .RunParallel (func (pb * testing.PB ) {
272
+ for pb .Next () {
273
+ _ , err := json .Marshal (tc .value )
274
+ if err != nil {
275
+ b .Errorf ("error marshalling JSON: %s" , err )
276
+ }
236
277
}
237
- }
278
+ })
238
279
})
239
- })
240
- }
280
+ }
281
+ })
241
282
}
242
283
243
284
func BenchmarkUnmarshal (b * testing.B ) {
244
- cases := [] struct {
285
+ type testcase struct {
245
286
desc string
246
- value interface {}
247
- }{
287
+ value any
288
+ dst func () any
289
+ }
290
+
291
+ cases := []testcase {
248
292
{
249
293
desc : "simple struct" ,
250
294
value : encodetestInstance ,
295
+ dst : func () any { return & encodetest {} },
251
296
},
252
297
{
253
298
desc : "nested struct" ,
254
299
value : nestedInstance ,
300
+ dst : func () any { return & encodetest {} },
255
301
},
302
+ }
303
+
304
+ inputs := []struct {
305
+ name string
306
+ value any
307
+ }{
256
308
{
257
- desc : "deep_bson.json.gz" ,
309
+ name : "simple" ,
310
+ value : encodetestInstance ,
311
+ },
312
+ {
313
+ name : "nested" ,
314
+ value : nestedInstance ,
315
+ },
316
+ {
317
+ name : "deep_bson.json.gz" ,
258
318
value : readExtJSONFile ("deep_bson.json.gz" ),
259
319
},
260
320
{
261
- desc : "flat_bson.json.gz" ,
321
+ name : "flat_bson.json.gz" ,
262
322
value : readExtJSONFile ("flat_bson.json.gz" ),
263
323
},
264
324
{
265
- desc : "full_bson.json.gz" ,
325
+ name : "full_bson.json.gz" ,
266
326
value : readExtJSONFile ("full_bson.json.gz" ),
267
327
},
268
328
}
269
329
270
- for _ , tc := range cases {
271
- b .Run (tc .desc , func (b * testing.B ) {
272
- b .Run ("BSON" , func (b * testing.B ) {
330
+ destinations := []struct {
331
+ name string
332
+ dst func () any
333
+ }{
334
+ {
335
+ name : "to map" ,
336
+ dst : func () any { return & map [string ]any {} },
337
+ },
338
+ {
339
+ name : "to D" ,
340
+ dst : func () any { return & D {} },
341
+ },
342
+ }
343
+
344
+ for _ , input := range inputs {
345
+ for _ , dest := range destinations {
346
+ cases = append (cases , testcase {
347
+ desc : input .name + " " + dest .name ,
348
+ value : input .value ,
349
+ dst : dest .dst ,
350
+ })
351
+ }
352
+ }
353
+
354
+ b .Run ("BSON" , func (b * testing.B ) {
355
+ for _ , tc := range cases {
356
+ tc := tc // Capture range variable.
357
+
358
+ b .Run (tc .desc , func (b * testing.B ) {
359
+ b .ReportAllocs ()
273
360
data , err := Marshal (tc .value )
274
361
if err != nil {
275
362
b .Errorf ("error marshalling BSON: %s" , err )
276
363
return
277
364
}
278
365
366
+ b .SetBytes (int64 (len (data )))
279
367
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 )
368
+ b .RunParallel (func (pb * testing.PB ) {
369
+ for pb .Next () {
370
+ val := tc .dst ()
371
+ err := Unmarshal (data , val )
372
+ if err != nil {
373
+ b .Errorf ("error unmarshalling BSON: %s" , err )
374
+ }
285
375
}
286
- }
376
+ })
287
377
})
378
+ }
379
+ })
380
+
381
+ b .Run ("extJSON" , func (b * testing.B ) {
382
+ for _ , tc := range cases {
383
+ tc := tc // Capture range variable.
288
384
289
- b .Run ("extJSON" , func (b * testing.B ) {
385
+ b .Run (tc .desc , func (b * testing.B ) {
386
+ b .ReportAllocs ()
290
387
data , err := MarshalExtJSON (tc .value , true , false )
291
388
if err != nil {
292
389
b .Errorf ("error marshalling extended JSON: %s" , err )
293
390
return
294
391
}
295
392
393
+ b .SetBytes (int64 (len (data )))
296
394
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 )
395
+ b .RunParallel (func (pb * testing.PB ) {
396
+ for pb .Next () {
397
+ val := tc .dst ()
398
+ err := UnmarshalExtJSON (data , true , val )
399
+ if err != nil {
400
+ b .Errorf ("error unmarshalling extended JSON: %s" , err )
401
+ }
302
402
}
303
- }
403
+ })
304
404
})
405
+ }
406
+ })
407
+
408
+ b .Run ("JSON" , func (b * testing.B ) {
409
+ for _ , tc := range cases {
410
+ tc := tc // Capture range variable.
305
411
306
- b .Run ("JSON" , func (b * testing.B ) {
412
+ b .Run (tc .desc , func (b * testing.B ) {
413
+ b .ReportAllocs ()
307
414
data , err := json .Marshal (tc .value )
308
415
if err != nil {
309
416
b .Errorf ("error marshalling JSON: %s" , err )
310
417
return
311
418
}
312
419
420
+ b .SetBytes (int64 (len (data )))
313
421
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 )
422
+ b .RunParallel (func (pb * testing.PB ) {
423
+ for pb .Next () {
424
+ val := tc .dst ()
425
+ err := json .Unmarshal (data , val )
426
+ if err != nil {
427
+ b .Errorf ("error unmarshalling JSON: %s" , err )
428
+ }
319
429
}
320
- }
430
+ })
321
431
})
322
- })
323
- }
432
+ }
433
+ })
324
434
}
325
435
326
436
// The following benchmarks are copied from the Go standard library's
@@ -389,13 +499,13 @@ func codeInit() {
389
499
}
390
500
391
501
func BenchmarkCodeUnmarshal (b * testing.B ) {
392
- b .ReportAllocs ()
393
502
if codeJSON == nil {
394
503
b .StopTimer ()
395
504
codeInit ()
396
505
b .StartTimer ()
397
506
}
398
507
b .Run ("BSON" , func (b * testing.B ) {
508
+ b .ReportAllocs ()
399
509
b .RunParallel (func (pb * testing.PB ) {
400
510
for pb .Next () {
401
511
var r codeResponse
@@ -407,6 +517,7 @@ func BenchmarkCodeUnmarshal(b *testing.B) {
407
517
b .SetBytes (int64 (len (codeBSON )))
408
518
})
409
519
b .Run ("JSON" , func (b * testing.B ) {
520
+ b .ReportAllocs ()
410
521
b .RunParallel (func (pb * testing.PB ) {
411
522
for pb .Next () {
412
523
var r codeResponse
@@ -420,13 +531,13 @@ func BenchmarkCodeUnmarshal(b *testing.B) {
420
531
}
421
532
422
533
func BenchmarkCodeMarshal (b * testing.B ) {
423
- b .ReportAllocs ()
424
534
if codeJSON == nil {
425
535
b .StopTimer ()
426
536
codeInit ()
427
537
b .StartTimer ()
428
538
}
429
539
b .Run ("BSON" , func (b * testing.B ) {
540
+ b .ReportAllocs ()
430
541
b .RunParallel (func (pb * testing.PB ) {
431
542
for pb .Next () {
432
543
if _ , err := Marshal (& codeStruct ); err != nil {
@@ -437,6 +548,7 @@ func BenchmarkCodeMarshal(b *testing.B) {
437
548
b .SetBytes (int64 (len (codeBSON )))
438
549
})
439
550
b .Run ("JSON" , func (b * testing.B ) {
551
+ b .ReportAllocs ()
440
552
b .RunParallel (func (pb * testing.PB ) {
441
553
for pb .Next () {
442
554
if _ , err := json .Marshal (& codeStruct ); err != nil {
0 commit comments