github.com/sandwich-go/boost@v1.3.29/xencoding/msgpack/msgpack_benchmark_test.go (about)

     1  package msgpack
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"github.com/sandwich-go/boost/xencoding"
     7  	"testing"
     8  
     9  	"github.com/sandwich-go/boost/xencoding/protobuf/test_perf"
    10  
    11  	"github.com/golang/protobuf/proto"
    12  )
    13  
    14  func setupBenchmarkCodecInputs(payloadBaseSize uint32) []proto.Message {
    15  	payloadBase := make([]byte, payloadBaseSize)
    16  	// arbitrary byte slices
    17  	payloadSuffixes := [][]byte{
    18  		[]byte("one"),
    19  		[]byte("two"),
    20  		[]byte("three"),
    21  		[]byte("four"),
    22  		[]byte("five"),
    23  	}
    24  	protoStructs := make([]proto.Message, 0)
    25  
    26  	for _, p := range payloadSuffixes {
    27  		ps := &test_perf.Buffer{}
    28  		ps.Body = append(payloadBase, p...)
    29  		protoStructs = append(protoStructs, ps)
    30  	}
    31  
    32  	return protoStructs
    33  }
    34  
    35  // The possible use of certain protobuf APIs like the proto.Buffer API potentially involves caching
    36  // on our side. This can add checks around memory allocations and possible contention.
    37  // Example run: go test -v -run=^$ -bench=BenchmarkMsgpackCodec -benchmem
    38  func BenchmarkMsgpackCodec(b *testing.B) {
    39  	// range of message sizes
    40  	payloadBaseSizes := make([]uint32, 0)
    41  	for i := uint32(0); i <= 12; i += 4 {
    42  		payloadBaseSizes = append(payloadBaseSizes, 1<<i)
    43  	}
    44  	// range of SetParallelism
    45  	parallelisms := make([]int, 0)
    46  	for i := uint32(0); i <= 16; i += 4 {
    47  		parallelisms = append(parallelisms, int(1<<i))
    48  	}
    49  	for _, s := range payloadBaseSizes {
    50  		for _, p := range parallelisms {
    51  			protoStructs := setupBenchmarkCodecInputs(s)
    52  			name := fmt.Sprintf("MinPayloadSize:%v/SetParallelism(%v)", s, p)
    53  			b.Run(name, func(b *testing.B) {
    54  				codec := &codec{}
    55  				b.SetParallelism(p)
    56  				b.RunParallel(func(pb *testing.PB) {
    57  					benchmarkCodec(codec, protoStructs, pb, b)
    58  				})
    59  			})
    60  		}
    61  	}
    62  }
    63  
    64  func benchmarkCodec(codec *codec, protoStructs []proto.Message, pb *testing.PB, b *testing.B) {
    65  	counter := 0
    66  	for pb.Next() {
    67  		counter++
    68  		ps := protoStructs[counter%len(protoStructs)]
    69  		fastMarshalAndUnmarshal(codec, ps, b)
    70  	}
    71  }
    72  
    73  func fastMarshalAndUnmarshal(codec xencoding.Codec, protoStruct proto.Message, b *testing.B) {
    74  	marshaledBytes, err := codec.Marshal(context.Background(), protoStruct)
    75  	if err != nil {
    76  		b.Errorf("codec.Marshal(_) returned an error")
    77  	}
    78  	res := test_perf.Buffer{}
    79  	if err := codec.Unmarshal(context.Background(), marshaledBytes, &res); err != nil {
    80  		b.Errorf("codec.Unmarshal(_) returned an error")
    81  	}
    82  }