@@ -19,6 +19,20 @@ import (
1919 "testing"
2020)
2121
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+
2236type encodetest struct {
2337 Field1String string
2438 Field1Int64 int64
@@ -184,7 +198,7 @@ func readExtJSONFile(filename string) map[string]interface{} {
184198func BenchmarkMarshal (b * testing.B ) {
185199 cases := []struct {
186200 desc string
187- value interface {}
201+ value any
188202 }{
189203 {
190204 desc : "simple struct" ,
@@ -194,6 +208,10 @@ func BenchmarkMarshal(b *testing.B) {
194208 desc : "nested struct" ,
195209 value : nestedInstance ,
196210 },
211+ {
212+ desc : "simple D" ,
213+ value : encodetestBsonD ,
214+ },
197215 {
198216 desc : "deep_bson.json.gz" ,
199217 value : readExtJSONFile ("deep_bson.json.gz" ),
@@ -208,119 +226,211 @@ func BenchmarkMarshal(b *testing.B) {
208226 },
209227 }
210228
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+ }
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 .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+ }
227259 }
228- }
260+ })
229261 })
262+ }
263+ })
230264
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+ }
236277 }
237- }
278+ })
238279 })
239- })
240- }
280+ }
281+ })
241282}
242283
243284func BenchmarkUnmarshal (b * testing.B ) {
244- cases := [] struct {
285+ type testcase struct {
245286 desc string
246- value interface {}
247- }{
287+ value any
288+ dst func () any
289+ }
290+
291+ cases := []testcase {
248292 {
249293 desc : "simple struct" ,
250294 value : encodetestInstance ,
295+ dst : func () any { return & encodetest {} },
251296 },
252297 {
253298 desc : "nested struct" ,
254299 value : nestedInstance ,
300+ dst : func () any { return & encodetest {} },
255301 },
302+ }
303+
304+ inputs := []struct {
305+ name string
306+ value any
307+ }{
256308 {
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" ,
258318 value : readExtJSONFile ("deep_bson.json.gz" ),
259319 },
260320 {
261- desc : "flat_bson.json.gz" ,
321+ name : "flat_bson.json.gz" ,
262322 value : readExtJSONFile ("flat_bson.json.gz" ),
263323 },
264324 {
265- desc : "full_bson.json.gz" ,
325+ name : "full_bson.json.gz" ,
266326 value : readExtJSONFile ("full_bson.json.gz" ),
267327 },
268328 }
269329
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 ()
273360 data , err := Marshal (tc .value )
274361 if err != nil {
275362 b .Errorf ("error marshalling BSON: %s" , err )
276363 return
277364 }
278365
366+ b .SetBytes (int64 (len (data )))
279367 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+ }
285375 }
286- }
376+ })
287377 })
378+ }
379+ })
380+
381+ b .Run ("extJSON" , func (b * testing.B ) {
382+ for _ , tc := range cases {
383+ tc := tc // Capture range variable.
288384
289- b .Run ("extJSON" , func (b * testing.B ) {
385+ b .Run (tc .desc , func (b * testing.B ) {
386+ b .ReportAllocs ()
290387 data , err := MarshalExtJSON (tc .value , true , false )
291388 if err != nil {
292389 b .Errorf ("error marshalling extended JSON: %s" , err )
293390 return
294391 }
295392
393+ b .SetBytes (int64 (len (data )))
296394 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+ }
302402 }
303- }
403+ })
304404 })
405+ }
406+ })
407+
408+ b .Run ("JSON" , func (b * testing.B ) {
409+ for _ , tc := range cases {
410+ tc := tc // Capture range variable.
305411
306- b .Run ("JSON" , func (b * testing.B ) {
412+ b .Run (tc .desc , func (b * testing.B ) {
413+ b .ReportAllocs ()
307414 data , err := json .Marshal (tc .value )
308415 if err != nil {
309416 b .Errorf ("error marshalling JSON: %s" , err )
310417 return
311418 }
312419
420+ b .SetBytes (int64 (len (data )))
313421 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+ }
319429 }
320- }
430+ })
321431 })
322- })
323- }
432+ }
433+ })
324434}
325435
326436// The following benchmarks are copied from the Go standard library's
@@ -389,13 +499,13 @@ func codeInit() {
389499}
390500
391501func BenchmarkCodeUnmarshal (b * testing.B ) {
392- b .ReportAllocs ()
393502 if codeJSON == nil {
394503 b .StopTimer ()
395504 codeInit ()
396505 b .StartTimer ()
397506 }
398507 b .Run ("BSON" , func (b * testing.B ) {
508+ b .ReportAllocs ()
399509 b .RunParallel (func (pb * testing.PB ) {
400510 for pb .Next () {
401511 var r codeResponse
@@ -407,6 +517,7 @@ func BenchmarkCodeUnmarshal(b *testing.B) {
407517 b .SetBytes (int64 (len (codeBSON )))
408518 })
409519 b .Run ("JSON" , func (b * testing.B ) {
520+ b .ReportAllocs ()
410521 b .RunParallel (func (pb * testing.PB ) {
411522 for pb .Next () {
412523 var r codeResponse
@@ -420,13 +531,13 @@ func BenchmarkCodeUnmarshal(b *testing.B) {
420531}
421532
422533func BenchmarkCodeMarshal (b * testing.B ) {
423- b .ReportAllocs ()
424534 if codeJSON == nil {
425535 b .StopTimer ()
426536 codeInit ()
427537 b .StartTimer ()
428538 }
429539 b .Run ("BSON" , func (b * testing.B ) {
540+ b .ReportAllocs ()
430541 b .RunParallel (func (pb * testing.PB ) {
431542 for pb .Next () {
432543 if _ , err := Marshal (& codeStruct ); err != nil {
@@ -437,6 +548,7 @@ func BenchmarkCodeMarshal(b *testing.B) {
437548 b .SetBytes (int64 (len (codeBSON )))
438549 })
439550 b .Run ("JSON" , func (b * testing.B ) {
551+ b .ReportAllocs ()
440552 b .RunParallel (func (pb * testing.PB ) {
441553 for pb .Next () {
442554 if _ , err := json .Marshal (& codeStruct ); err != nil {
0 commit comments