github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/testdata/baseline_p2j_test.go (about)

     1  package testdata
     2  
     3  import (
     4  	"context"
     5  	ejson "encoding/json"
     6  	"errors"
     7  	"testing"
     8  
     9  	"github.com/bytedance/sonic"
    10  	"github.com/cloudwego/dynamicgo/conv"
    11  	"github.com/cloudwego/dynamicgo/conv/p2j"
    12  	"github.com/cloudwego/dynamicgo/proto"
    13  	"github.com/cloudwego/dynamicgo/testdata/kitex_gen/pb/baseline"
    14  	"github.com/stretchr/testify/require"
    15  	"google.golang.org/protobuf/encoding/protowire"
    16  )
    17  
    18  func getPbSimpleDesc() *proto.TypeDescriptor {
    19  	return proto.FnRequest(proto.GetFnDescFromFile(protoPath, "SimpleMethod", proto.Options{}))
    20  }
    21  
    22  func getPbPartialSimpleDesc() *proto.TypeDescriptor {
    23  	return proto.FnRequest(proto.GetFnDescFromFile(protoPath, "PartialSimpleMethod", proto.Options{}))
    24  }
    25  
    26  func getPbNestingDesc() *proto.TypeDescriptor {
    27  	return proto.FnRequest(proto.GetFnDescFromFile(protoPath, "NestingMethod", proto.Options{}))
    28  }
    29  
    30  func getPbPartialNestingDesc() *proto.TypeDescriptor {
    31  	return proto.FnRequest(proto.GetFnDescFromFile(protoPath, "PartialNestingMethod", proto.Options{}))
    32  }
    33  
    34  func FastReadPbSimpleObject(bakBuf []byte, obj *baseline.Simple) error {
    35  	l := 0
    36  	datalen := len(bakBuf)
    37  	for l < datalen {
    38  		id, wtyp, tagLen := protowire.ConsumeTag(bakBuf)
    39  		if tagLen < 0 {
    40  			return errors.New("proto data error format")
    41  		}
    42  		l += tagLen
    43  		bakBuf = bakBuf[tagLen:]
    44  		offset, err := obj.FastRead(bakBuf, int8(wtyp), int32(id))
    45  		if err != nil {
    46  			return err
    47  		}
    48  		bakBuf = bakBuf[offset:]
    49  		l += offset
    50  	}
    51  	if len(bakBuf) != 0 {
    52  		return errors.New("proto data error format")
    53  	}
    54  	return nil
    55  }
    56  
    57  func FastReadPbMediumObject(bakBuf []byte, obj *baseline.Nesting) error {
    58  	l := 0
    59  	datalen := len(bakBuf)
    60  	for l < datalen {
    61  		id, wtyp, tagLen := protowire.ConsumeTag(bakBuf)
    62  		if tagLen < 0 {
    63  			return errors.New("proto data error format")
    64  		}
    65  		l += tagLen
    66  		bakBuf = bakBuf[tagLen:]
    67  		offset, err := obj.FastRead(bakBuf, int8(wtyp), int32(id))
    68  		if err != nil {
    69  			return err
    70  		}
    71  		bakBuf = bakBuf[offset:]
    72  		l += offset
    73  	}
    74  	if len(bakBuf) != 0 {
    75  		return errors.New("proto data error format")
    76  	}
    77  	return nil
    78  }
    79  
    80  func TestProtobuf2JSON(t *testing.T) {
    81  	t.Run("small", func(t *testing.T) {
    82  		ctx := context.Background()
    83  		desc := getPbSimpleDesc()
    84  		// kitex to build pbData, and serialize into bytes
    85  		data := getPbSimpleValue()
    86  		cv := p2j.NewBinaryConv(conv.Options{})
    87  		in := make([]byte, data.Size())
    88  		data.FastWrite(in)
    89  
    90  		ret, err := cv.Do(ctx, desc, in)
    91  		if err != nil {
    92  			t.Fatal(err)
    93  		}
    94  		println(string(ret))
    95  
    96  		// unserialize json to object
    97  		v := &baseline.Simple{}
    98  		if err := ejson.Unmarshal(ret, v); err != nil {
    99  			t.Fatal(err)
   100  		}
   101  		require.Equal(t, data, v)
   102  	})
   103  
   104  	t.Run("medium", func(t *testing.T) {
   105  		ctx := context.Background()
   106  		desc := getPbNestingDesc()
   107  		// kitex to build pbData, and serialize into bytes
   108  		data := getPbNestingValue()
   109  		cv := p2j.NewBinaryConv(conv.Options{})
   110  		in := make([]byte, data.Size())
   111  		data.FastWrite(in)
   112  
   113  		ret, err := cv.Do(ctx, desc, in)
   114  		if err != nil {
   115  			t.Fatal(err)
   116  		}
   117  		println(string(ret))
   118  
   119  		// unserialize json to object
   120  		v := &baseline.Nesting{}
   121  		if err := ejson.Unmarshal(ret, v); err != nil {
   122  			t.Fatal(err)
   123  		}
   124  		require.Equal(t, data, v)
   125  	})
   126  }
   127  
   128  func BenchmarkProtobuf2JSON_DynamicGo_Raw(b *testing.B) {
   129  	b.Run("small", func(b *testing.B) {
   130  		ctx := context.Background()
   131  		desc := getPbSimpleDesc()
   132  		// kitex to build pbData, and serialize into bytes
   133  		data := getPbSimpleValue()
   134  		cv := p2j.NewBinaryConv(conv.Options{})
   135  		in := make([]byte, data.Size())
   136  		data.FastWrite(in)
   137  
   138  		_, err := cv.Do(ctx, desc, in)
   139  		if err != nil {
   140  			b.Fatal(err)
   141  		}
   142  		b.SetBytes(int64(len(in)))
   143  		b.ResetTimer()
   144  		for i := 0; i < b.N; i++ {
   145  			_, _ = cv.Do(ctx, desc, in)
   146  		}
   147  	})
   148  
   149  	b.Run("medium", func(b *testing.B) {
   150  		ctx := context.Background()
   151  		desc := getPbNestingDesc()
   152  		// kitex to build pbData, and serialize into bytes
   153  		data := getPbNestingValue()
   154  		cv := p2j.NewBinaryConv(conv.Options{})
   155  		in := make([]byte, data.Size())
   156  		data.FastWrite(in)
   157  
   158  		_, err := cv.Do(ctx, desc, in)
   159  		if err != nil {
   160  			b.Fatal(err)
   161  		}
   162  		b.SetBytes(int64(len(in)))
   163  		b.ResetTimer()
   164  		for i := 0; i < b.N; i++ {
   165  			_, _ = cv.Do(ctx, desc, in)
   166  		}
   167  	})
   168  }
   169  
   170  func BenchmarkProtobuf2JSON_SonicAndKitex(b *testing.B) {
   171  	b.Run("small", func(b *testing.B) {
   172  		v := getPbSimpleValue()
   173  		var buf = make([]byte, v.Size())
   174  		v.FastWrite(buf)
   175  
   176  		// kitex_fastRead build object
   177  		obj := &baseline.Simple{}
   178  		if err := FastReadPbSimpleObject(buf, obj); err != nil {
   179  			b.Fatal(err)
   180  		}
   181  
   182  		// sonic marshal object
   183  		_, err := sonic.Marshal(obj)
   184  		if err != nil {
   185  			b.Fatal(err)
   186  		}
   187  		// println(string(out))
   188  
   189  		b.SetBytes(int64(len(buf)))
   190  		b.ResetTimer()
   191  		for i := 0; i < b.N; i++ {
   192  			obj := &baseline.Simple{}
   193  			_ = FastReadPbSimpleObject(buf, obj)
   194  			_, _ = sonic.Marshal(obj)
   195  		}
   196  	})
   197  
   198  	b.Run("medium", func(b *testing.B) {
   199  		v := getPbNestingValue()
   200  		var buf = make([]byte, v.Size())
   201  		v.FastWrite(buf)
   202  
   203  		// kitex_fastRead build object
   204  		obj := &baseline.Nesting{}
   205  		if err := FastReadPbMediumObject(buf, obj); err != nil {
   206  			b.Fatal(err)
   207  		}
   208  
   209  		// sonic marshal object
   210  		_, err := sonic.Marshal(obj)
   211  		if err != nil {
   212  			b.Fatal(err)
   213  		}
   214  		// println(string(out))
   215  
   216  		b.SetBytes(int64(len(buf)))
   217  		b.ResetTimer()
   218  		for i := 0; i < b.N; i++ {
   219  			obj := &baseline.Nesting{}
   220  			_ = FastReadPbMediumObject(buf, obj)
   221  			_, _ = sonic.Marshal(obj)
   222  		}
   223  	})
   224  }
   225  
   226  // func BenchmarkProtobuf2JSON_ProtoBufGo(b *testing.B) {
   227  // 	b.Run("small", func(b *testing.B) {
   228  // 		data := getPbSimpleValue()
   229  // 		out, err := protojson.Marshal(data.ProtoReflect().Interface())
   230  // 		if err != nil {
   231  // 			b.Fatal(err)
   232  // 		}
   233  // 		// println(string(out))
   234  
   235  // 		b.SetBytes(int64(len(out)))
   236  // 		b.ResetTimer()
   237  // 		for i := 0; i < b.N; i++ {
   238  // 			_, _ = protojson.Marshal(data.ProtoReflect().Interface())
   239  // 		}
   240  // 	})
   241  
   242  // 	b.Run("medium", func(b *testing.B) {
   243  // 		data := getPbNestingValue()
   244  // 		out, err := protojson.Marshal(data.ProtoReflect().Interface())
   245  // 		if err != nil {
   246  // 			b.Fatal(err)
   247  // 		}
   248  // 		// println(string(out))
   249  
   250  // 		b.SetBytes(int64(len(out)))
   251  // 		b.ResetTimer()
   252  // 		for i := 0; i < b.N; i++ {
   253  // 			_, _ = protojson.Marshal(data.ProtoReflect().Interface())
   254  // 		}
   255  // 	})
   256  // }