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

     1  package testdata
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"math"
     7  	"reflect"
     8  	"strconv"
     9  	"testing"
    10  
    11  	"github.com/cloudwego/dynamicgo/proto"
    12  	"github.com/cloudwego/dynamicgo/proto/binary"
    13  	"github.com/cloudwego/dynamicgo/proto/generic"
    14  	"github.com/cloudwego/dynamicgo/testdata/kitex_gen/pb/baseline"
    15  	"github.com/stretchr/testify/require"
    16  	goprotowire "google.golang.org/protobuf/encoding/protowire"
    17  )
    18  
    19  func init() {
    20  	sobj := getPbSimpleValue()
    21  	println("small protobuf data size: ", sobj.Size())
    22  
    23  	psobj := getPbPartialSimpleValue()
    24  	println("small protobuf data size: ", psobj.Size())
    25  
    26  	nobj := getPbNestingValue()
    27  	println("medium protobuf data size: ", nobj.Size())
    28  
    29  	pnobj := getPbPartialNestingValue()
    30  	println("medium protobuf data size: ", pnobj.Size())
    31  }
    32  
    33  /*
    34   * performance test in DynamicGo
    35   * 1. ProtoSkip
    36   * 2. ProtoGetOne
    37   * 3. ProtoGetMany
    38   * 4. ProtoSetOne
    39   * 5. ProtoSetMany
    40   * 6. ProtoMarshalMany
    41   * 7. ProtoMarshalTo, compared with ProtoBufGo, KitexFast
    42   */
    43  func BenchmarkProtoSkip_DynamicGo(b *testing.B) {
    44  	b.Run("small", func(b *testing.B) {
    45  		desc := getPbSimpleDesc()
    46  		obj := getPbSimpleValue()
    47  		data := make([]byte, obj.Size())
    48  		ret := obj.FastWrite(data)
    49  		if ret != len(data) {
    50  			b.Fatal(ret)
    51  		}
    52  
    53  		p := binary.NewBinaryProtol(data)
    54  		for p.Left() > 0 {
    55  			fieldNumber, wireType, _, err := p.ConsumeTag()
    56  			if err != nil {
    57  				b.Fatal(err)
    58  			}
    59  
    60  			if desc.Message().ByNumber(fieldNumber) == nil {
    61  				b.Fatal("field not found")
    62  			}
    63  
    64  			if err := p.Skip(wireType, false); err != nil {
    65  				b.Fatal(err)
    66  			}
    67  		}
    68  
    69  		require.Equal(b, len(data), p.Read)
    70  
    71  		b.SetBytes(int64(len(data)))
    72  		b.ResetTimer()
    73  		b.Run("go", func(b *testing.B) {
    74  			for i := 0; i < b.N; i++ {
    75  				p := binary.NewBinaryProtol(data)
    76  				for p.Left() > 0 {
    77  					_, wireType, _, _ := p.ConsumeTag()
    78  					_ = p.Skip(wireType, false)
    79  				}
    80  			}
    81  		})
    82  	})
    83  
    84  	b.Run("medium", func(b *testing.B) {
    85  		desc := getPbNestingDesc()
    86  		obj := getPbNestingValue()
    87  		data := make([]byte, obj.Size())
    88  		ret := obj.FastWrite(data)
    89  		if ret != len(data) {
    90  			b.Fatal(ret)
    91  		}
    92  
    93  		p := binary.NewBinaryProtol(data)
    94  		for p.Left() > 0 {
    95  			fieldNumber, wireType, _, err := p.ConsumeTag()
    96  			if err != nil {
    97  				b.Fatal(err)
    98  			}
    99  
   100  			if desc.Message().ByNumber(fieldNumber) == nil {
   101  				b.Fatal("field not found")
   102  			}
   103  
   104  			if err := p.Skip(wireType, false); err != nil {
   105  				b.Fatal(err)
   106  			}
   107  		}
   108  
   109  		require.Equal(b, len(data), p.Read)
   110  
   111  		b.SetBytes(int64(len(data)))
   112  		b.ResetTimer()
   113  		b.Run("go", func(b *testing.B) {
   114  			for i := 0; i < b.N; i++ {
   115  				p := binary.NewBinaryProtol(data)
   116  				for p.Left() > 0 {
   117  					_, wireType, _, _ := p.ConsumeTag()
   118  					_ = p.Skip(wireType, false)
   119  				}
   120  			}
   121  		})
   122  	})
   123  }
   124  
   125  func BenchmarkProtoGetOne_DynamicGo(b *testing.B) {
   126  	b.Run("small", func(b *testing.B) {
   127  		desc := getPbSimpleDesc()
   128  		obj := getPbSimpleValue()
   129  		data := make([]byte, obj.Size())
   130  		ret := obj.FastWrite(data)
   131  		if ret != len(data) {
   132  			b.Fatal(ret)
   133  		}
   134  
   135  		v := generic.NewRootValue(desc, data)
   136  		vv := v.GetByPath(generic.NewPathFieldId(6))
   137  		require.Nil(b, vv.Check())
   138  		bs, err := vv.Binary()
   139  		require.Nil(b, err)
   140  		require.Equal(b, obj.BinaryField, bs)
   141  		b.SetBytes(int64(len(data)))
   142  		b.ResetTimer()
   143  		b.Run("go", func(b *testing.B) {
   144  			for i := 0; i < b.N; i++ {
   145  				_ = v.GetByPath(generic.NewPathFieldId(6))
   146  			}
   147  		})
   148  	})
   149  
   150  	b.Run("medium", func(b *testing.B) {
   151  		desc := getPbNestingDesc()
   152  		obj := getPbNestingValue()
   153  		data := make([]byte, obj.Size())
   154  		ret := obj.FastWrite(data)
   155  		if ret != len(data) {
   156  			b.Fatal(ret)
   157  		}
   158  
   159  		v := generic.NewRootValue(desc, data)
   160  		vv := v.GetByPath(generic.NewPathFieldId(15), generic.NewPathStrKey("15"), generic.NewPathFieldId(6))
   161  		require.Nil(b, vv.Check())
   162  		bs, err := vv.Binary()
   163  		require.Nil(b, err)
   164  		require.Equal(b, obj.MapStringSimple["15"].BinaryField, bs)
   165  		b.SetBytes(int64(len(data)))
   166  		b.ResetTimer()
   167  		b.Run("go", func(b *testing.B) {
   168  			for i := 0; i < b.N; i++ {
   169  				_ = v.GetByPath(generic.NewPathFieldId(15), generic.NewPathStrKey("15"), generic.NewPathFieldId(6))
   170  			}
   171  		})
   172  	})
   173  }
   174  
   175  // func BenchmarkProtoGetOne_ProtobufGo(b *testing.B) {
   176  // 	b.Run("small", func(b *testing.B) {
   177  // 		// build desc、obj
   178  // 		desc := getPbSimpleDesc()
   179  // 		obj := getPbSimpleValue()
   180  // 		data := make([]byte, obj.Size())
   181  // 		ret := obj.FastWrite(data)
   182  // 		if ret != len(data) {
   183  // 			b.Fatal(ret)
   184  // 		}
   185  // 		// build dynamicpb Message
   186  // 		message := dynamicpb.NewMessage(*desc)
   187  // 		if err := goproto.Unmarshal(data, message); err != nil {
   188  // 			b.Fatal("build dynamicpb failed")
   189  // 		}
   190  // 		targetDesc := (*desc).Fields().ByNumber(6)
   191  // 		if !message.Has(targetDesc) {
   192  // 			b.Fatal("dynamicpb can't find targetDesc")
   193  // 		}
   194  // 		value := message.Get(targetDesc)
   195  // 		require.Equal(b, obj.BinaryField, value.Bytes())
   196  // 		b.ResetTimer()
   197  // 		b.Run("go", func(b *testing.B) {
   198  // 			for i := 0; i < b.N; i++ {
   199  // 				_ = goproto.Unmarshal(data, message)
   200  // 				_ = message.Get(targetDesc)
   201  // 				// _ = goproto.Marshal(message)
   202  // 			}
   203  // 		})
   204  // 	})
   205  
   206  // 	// todo: medium data test, have no idea to get the inner data in MapStringSimple["15"].BinaryField?
   207  // }
   208  
   209  
   210  func BenchmarkProtoSetOne_DynamicGo(b *testing.B) {
   211  	b.Run("small", func(b *testing.B) {
   212  		desc := getPbSimpleDesc()
   213  		obj := getPbSimpleValue()
   214  		data := make([]byte, obj.Size())
   215  		ret := obj.FastWrite(data)
   216  		if ret != len(data) {
   217  			b.Fatal(ret)
   218  		}
   219  		v := generic.NewRootValue(desc, data)
   220  		p := binary.NewBinaryProtocolBuffer()
   221  		p.WriteBytes(obj.BinaryField)
   222  		fd6 := desc.Message().ByNumber(6).Type()
   223  		n := generic.NewValue(fd6, p.Buf)
   224  		_, err := v.SetByPath(n.Node, generic.NewPathFieldId(6))
   225  		require.Nil(b, err)
   226  		nn := v.GetByPath(generic.NewPathFieldId(6))
   227  		require.Equal(b, n.Raw(), nn.Raw())
   228  
   229  		b.SetBytes(int64(len(data)))
   230  		b.ResetTimer()
   231  		b.Run("go", func(b *testing.B) {
   232  			for i := 0; i < b.N; i++ {
   233  				_, _ = v.SetByPath(n.Node, generic.NewPathFieldId(6))
   234  			}
   235  		})
   236  	})
   237  
   238  	b.Run("medium", func(b *testing.B) {
   239  		desc := getPbNestingDesc()
   240  		obj := getPbNestingValue()
   241  		data := make([]byte, obj.Size())
   242  		ret := obj.FastWrite(data)
   243  		if ret != len(data) {
   244  			b.Fatal(ret)
   245  		}
   246  
   247  		v := generic.NewRootValue(desc, data)
   248  		p := binary.NewBinaryProtocolBuffer()
   249  		p.WriteBytes(obj.MapStringSimple["15"].BinaryField)
   250  		fd15 := desc.Message().ByNumber(15).MapValue().Message().ByNumber(6).Type()
   251  		n := generic.NewValue(fd15, p.Buf)
   252  		_, err := v.SetByPath(n.Node, generic.NewPathFieldId(15), generic.NewPathStrKey("15"), generic.NewPathFieldId(6))
   253  		require.Nil(b, err)
   254  		nn := v.GetByPath(generic.NewPathFieldId(15), generic.NewPathStrKey("15"), generic.NewPathFieldId(6))
   255  		require.Equal(b, n.Raw(), nn.Raw())
   256  
   257  		b.SetBytes(int64(len(data)))
   258  		b.ResetTimer()
   259  		b.Run("go", func(b *testing.B) {
   260  			for i := 0; i < b.N; i++ {
   261  				_, _ = v.SetByPath(n.Node, generic.NewPathFieldId(15), generic.NewPathStrKey("15"), generic.NewPathFieldId(6))
   262  			}
   263  		})
   264  	})
   265  }
   266  
   267  // func BenchmarkProtoSetOne_ProtobufGo(b *testing.B) {
   268  // 	b.Run("small", func(b *testing.B) {
   269  // 		desc := getPbSimpleDesc()
   270  // 		obj := getPbSimpleValue()
   271  // 		data := make([]byte, obj.Size())
   272  // 		ret := obj.FastWrite(data)
   273  // 		if ret != len(data) {
   274  // 			b.Fatal(ret)
   275  // 		}
   276  // 		message := dynamicpb.NewMessage(*desc)
   277  // 		targetDesc := (*desc).Fields().ByNumber(6)
   278  // 		if err := goproto.Unmarshal(data, message); err != nil {
   279  // 			b.Fatal("build dynamicpb failed")
   280  // 		}
   281  // 		fieldValue := protoreflect.ValueOfBytes(obj.BinaryField)
   282  // 		message.Set(targetDesc, fieldValue)
   283  // 		if !message.Has(targetDesc) {
   284  // 			b.Fatal("dynamicpb can't find targetDesc")
   285  // 		}
   286  // 		find := message.Get(targetDesc)
   287  // 		require.Equal(b, obj.BinaryField, find.Bytes())
   288  // 		b.ResetTimer()
   289  // 		b.Run("go", func(b *testing.B) {
   290  // 			for i := 0; i < b.N; i++ {
   291  // 				message = dynamicpb.NewMessage(*desc)
   292  // 				_ = goproto.Unmarshal(data, message)
   293  // 				fieldValue := protoreflect.ValueOfBytes(obj.BinaryField)
   294  // 				message.Set(targetDesc, fieldValue)
   295  // 			}
   296  // 		})
   297  // 	})
   298  
   299  // 	// todo: medium data test, have no idea to set the inner data in MapStringSimple["15"].BinaryField?
   300  // }
   301  
   302  func BenchmarkProtoGetMany_DynamicGo(b *testing.B) {
   303  	b.Run("small", func(b *testing.B) {
   304  		desc := getPbSimpleDesc()
   305  		obj := getPbSimpleValue()
   306  		data := make([]byte, obj.Size())
   307  		ret := obj.FastWrite(data)
   308  		if ret != len(data) {
   309  			b.Fatal(ret)
   310  		}
   311  
   312  		opts := generic.Options{}
   313  
   314  		v := generic.NewRootValue(desc, data)
   315  
   316  		ps := []generic.PathNode{
   317  			{Path: generic.NewPathFieldId(1)},
   318  			{Path: generic.NewPathFieldId(3)},
   319  			{Path: generic.NewPathFieldId(6)},
   320  		}
   321  
   322  		err := v.GetMany(ps, &opts)
   323  		require.Nil(b, err)
   324  
   325  		opts.UseNativeSkip = false
   326  		b.SetBytes(int64(len(data)))
   327  		b.ResetTimer()
   328  		b.Run("go", func(b *testing.B) {
   329  			for i := 0; i < b.N; i++ {
   330  				_ = v.GetMany(ps, &opts)
   331  			}
   332  		})
   333  	})
   334  
   335  	b.Run("medium", func(b *testing.B) {
   336  		desc := getPbNestingDesc()
   337  		obj := getPbNestingValue()
   338  		data := make([]byte, obj.Size())
   339  		ret := obj.FastWrite(data)
   340  		if ret != len(data) {
   341  			b.Fatal(ret)
   342  		}
   343  
   344  		opts := generic.Options{}
   345  
   346  		v := generic.NewRootValue(desc, data)
   347  
   348  		ps := []generic.PathNode{
   349  			{Path: generic.NewPathFieldId(2)},
   350  			{Path: generic.NewPathFieldId(8)},
   351  			{Path: generic.NewPathFieldId(15)},
   352  		}
   353  
   354  		err := v.GetMany(ps, &opts)
   355  		require.Nil(b, err)
   356  
   357  		opts.UseNativeSkip = false
   358  		b.SetBytes(int64(len(data)))
   359  		b.ResetTimer()
   360  		b.Run("go", func(b *testing.B) {
   361  			for i := 0; i < b.N; i++ {
   362  				_ = v.GetMany(ps, &opts)
   363  			}
   364  		})
   365  	})
   366  }
   367  
   368  func BenchmarkProtoSetMany_DynamicGo(b *testing.B) {
   369  	b.Run("small", func(b *testing.B) {
   370  		desc := getPbSimpleDesc()
   371  		obj := getPbSimpleValue()
   372  		data := make([]byte, obj.Size())
   373  		ret := obj.FastWrite(data)
   374  		if ret != len(data) {
   375  			panic(ret)
   376  		}
   377  
   378  		opts := generic.Options{}
   379  		v := generic.NewRootValue(desc, data)
   380  		ps := []generic.PathNode{
   381  			{Path: generic.NewPathFieldId(1)},
   382  			{Path: generic.NewPathFieldId(3)},
   383  			{Path: generic.NewPathFieldId(6)},
   384  		}
   385  
   386  		adress2root := make([]int, 0)
   387  		path2root := make([]generic.Path, 0)
   388  		require.Nil(b, v.GetMany(ps, &opts))
   389  		require.Nil(b, v.SetMany(ps, &opts, &v, adress2root, path2root...))
   390  		opts.UseNativeSkip = false
   391  		b.SetBytes(int64(len(data)))
   392  		b.ResetTimer()
   393  		b.Run("go", func(b *testing.B) {
   394  			for i := 0; i < b.N; i++ {
   395  				_ = v.SetMany(ps, &opts, &v, adress2root, path2root...)
   396  			}
   397  		})
   398  	})
   399  
   400  	b.Run("medium", func(b *testing.B) {
   401  		desc := getPbNestingDesc()
   402  		obj := getPbNestingValue()
   403  		data := make([]byte, obj.Size())
   404  		ret := obj.FastWrite(data)
   405  		if ret != len(data) {
   406  			panic(ret)
   407  		}
   408  
   409  		opts := generic.Options{}
   410  		v := generic.NewRootValue(desc, data)
   411  		ps := []generic.PathNode{
   412  			{Path: generic.NewPathFieldId(2)},
   413  			{Path: generic.NewPathFieldId(8)},
   414  			{Path: generic.NewPathFieldId(15)},
   415  		}
   416  
   417  		adress2root := make([]int, 0)
   418  		path2root := make([]generic.Path, 0)
   419  		require.Nil(b, v.GetMany(ps, &opts))
   420  		require.Nil(b, v.SetMany(ps, &opts, &v, adress2root, path2root...))
   421  		opts.UseNativeSkip = false
   422  		b.SetBytes(int64(len(data)))
   423  		b.ResetTimer()
   424  		b.Run("go", func(b *testing.B) {
   425  			for i := 0; i < b.N; i++ {
   426  				_ = v.SetMany(ps, &opts, &v, adress2root, path2root...)
   427  			}
   428  		})
   429  	})
   430  }
   431  
   432  func BenchmarkProtoMarshalMany_DynamicGo(b *testing.B) {
   433  	b.Run("small", func(b *testing.B) {
   434  		desc := getPbSimpleDesc()
   435  		obj := getPbSimpleValue()
   436  		data := make([]byte, obj.Size())
   437  		ret := obj.FastWrite(data)
   438  		if ret != len(data) {
   439  			b.Fatal(ret)
   440  		}
   441  
   442  		opts := generic.Options{}
   443  
   444  		v := generic.NewRootValue(desc, data)
   445  		ps := []generic.PathNode{
   446  			{Path: generic.NewPathFieldId(1)},
   447  			{Path: generic.NewPathFieldId(3)},
   448  			{Path: generic.NewPathFieldId(6)},
   449  		}
   450  
   451  		err := v.GetMany(ps, &opts)
   452  		require.Nil(b, err)
   453  
   454  		n := generic.PathNode{
   455  			Path: generic.NewPathFieldId(1),
   456  			Node: v.Node,
   457  			Next: ps,
   458  		}
   459  
   460  		buf, err := n.Marshal(&opts)
   461  		require.Nil(b, err)
   462  		exp := baseline.PartialSimple{}
   463  		dataLen := len(buf)
   464  		l := 0
   465  		for l < dataLen {
   466  			id, wtyp, tagLen := goprotowire.ConsumeTag(buf)
   467  			if tagLen < 0 {
   468  				b.Fatal("test failed")
   469  			}
   470  			l += tagLen
   471  			buf = buf[tagLen:]
   472  			offset, err := exp.FastRead(buf, int8(wtyp), int32(id))
   473  			require.Nil(b, err)
   474  			buf = buf[offset:]
   475  			l += offset
   476  		}
   477  		if len(buf) != 0 {
   478  			b.Fatal("test failed")
   479  		}
   480  		b.SetBytes(int64(len(data)))
   481  		b.ResetTimer()
   482  		for i := 0; i < b.N; i++ {
   483  			_, _ = n.Marshal(&opts)
   484  		}
   485  	})
   486  
   487  	b.Run("medium", func(b *testing.B) {
   488  		desc := getPbNestingDesc()
   489  		obj := getPbNestingValue()
   490  		data := make([]byte, obj.Size())
   491  		ret := obj.FastWrite(data)
   492  		if ret != len(data) {
   493  			b.Fatal(ret)
   494  		}
   495  		opts := generic.Options{}
   496  		v := generic.NewRootValue(desc, data)
   497  		ps := []generic.PathNode{
   498  			{Path: generic.NewPathFieldId(2)},
   499  			{Path: generic.NewPathFieldId(8)},
   500  			{Path: generic.NewPathFieldId(15)},
   501  		}
   502  		err := v.GetMany(ps, &opts)
   503  		require.Nil(b, err)
   504  		n := generic.PathNode{
   505  			Path: generic.NewPathFieldId(2),
   506  			Node: v.Node,
   507  			Next: ps,
   508  		}
   509  		buf, err := n.Marshal(&opts)
   510  		require.Nil(b, err)
   511  		exp := baseline.PartialNesting{}
   512  		dataLen := len(buf)
   513  		l := 0
   514  		for l < dataLen {
   515  			id, wtyp, tagLen := goprotowire.ConsumeTag(buf)
   516  			if tagLen < 0 {
   517  				b.Fatal("test failed")
   518  			}
   519  			l += tagLen
   520  			buf = buf[tagLen:]
   521  			offset, err := exp.FastRead(buf, int8(wtyp), int32(id))
   522  			require.Nil(b, err)
   523  			buf = buf[offset:]
   524  			l += offset
   525  		}
   526  		if len(buf) != 0 {
   527  			b.Fatal("test failed")
   528  		}
   529  		b.SetBytes(int64(len(data)))
   530  		b.ResetTimer()
   531  		for i := 0; i < b.N; i++ {
   532  			_, _ = n.Marshal(&opts)
   533  		}
   534  	})
   535  }
   536  
   537  func BenchmarkProtoMarshalTo_DynamicGo(b *testing.B) {
   538  	b.Run("small", func(b *testing.B) {
   539  		desc := getPbSimpleDesc()
   540  		part := getPbPartialSimpleDesc()
   541  		obj := getPbSimpleValue()
   542  		data := make([]byte, obj.Size())
   543  		ret := obj.FastWrite(data)
   544  		if ret != len(data) {
   545  			b.Fatal(ret)
   546  		}
   547  		opts := generic.Options{}
   548  		v := generic.NewRootValue(desc, data)
   549  		out, err := v.MarshalTo(part, &opts)
   550  		require.Nil(b, err)
   551  		// fast read check
   552  		exp := baseline.PartialSimple{}
   553  		dataLen := len(out)
   554  		l := 0
   555  		for l < dataLen {
   556  			id, wtyp, tagLen := goprotowire.ConsumeTag(out)
   557  			if tagLen < 0 {
   558  				b.Fatal("test failed")
   559  			}
   560  			l += tagLen
   561  			out = out[tagLen:]
   562  			offset, err := exp.FastRead(out, int8(wtyp), int32(id))
   563  			require.Nil(b, err)
   564  			out = out[offset:]
   565  			l += offset
   566  		}
   567  		if len(out) != 0 {
   568  			b.Fatal("test failed")
   569  		}
   570  
   571  		opts = generic.Options{
   572  			UseNativeSkip: false,
   573  		}
   574  		b.SetBytes(int64(len(data)))
   575  		b.ResetTimer()
   576  
   577  		b.Run("go", func(b *testing.B) {
   578  			for i := 0; i < b.N; i++ {
   579  				_, _ = v.MarshalTo(part, &opts)
   580  			}
   581  		})
   582  	})
   583  
   584  	b.Run("medium", func(b *testing.B) {
   585  		desc := getPbNestingDesc()
   586  		part := getPbPartialNestingDesc()
   587  		obj := getPbNestingValue()
   588  		data := make([]byte, obj.Size())
   589  		ret := obj.FastWrite(data)
   590  		if ret != len(data) {
   591  			b.Fatal(ret)
   592  		}
   593  		opts := generic.Options{}
   594  		v := generic.NewRootValue(desc, data)
   595  		out, err := v.MarshalTo(part, &opts)
   596  		require.Nil(b, err)
   597  		// fast read check
   598  		exp := baseline.PartialSimple{}
   599  		dataLen := len(out)
   600  		l := 0
   601  		for l < dataLen {
   602  			id, wtyp, tagLen := goprotowire.ConsumeTag(out)
   603  			if tagLen < 0 {
   604  				b.Fatal("test failed")
   605  			}
   606  			l += tagLen
   607  			out = out[tagLen:]
   608  			offset, err := exp.FastRead(out, int8(wtyp), int32(id))
   609  			require.Nil(b, err)
   610  			out = out[offset:]
   611  			l += offset
   612  		}
   613  		if len(out) != 0 {
   614  			b.Fatal("test failed")
   615  		}
   616  
   617  		opts = generic.Options{
   618  			UseNativeSkip: false,
   619  		}
   620  		b.SetBytes(int64(len(data)))
   621  		b.ResetTimer()
   622  
   623  		b.Run("go", func(b *testing.B) {
   624  			for i := 0; i < b.N; i++ {
   625  				_, _ = v.MarshalTo(part, &opts)
   626  			}
   627  		})
   628  	})
   629  }
   630  
   631  func marshaltoPartialSimple_KitexFast(data []byte, exp *baseline.PartialSimple) error {
   632  	dataLen := len(data)
   633  	l := 0
   634  	for l < dataLen {
   635  		id, wtyp, tagLen := goprotowire.ConsumeTag(data)
   636  		if tagLen < 0 {
   637  			return errors.New("test failed")
   638  		}
   639  		l += tagLen
   640  		data = data[tagLen:]
   641  		offset, _ := exp.FastRead(data, int8(wtyp), int32(id))
   642  		data = data[offset:]
   643  		l += offset
   644  	}
   645  	data2 := make([]byte, exp.Size())
   646  	_ = exp.FastWrite(data2)
   647  	return nil
   648  }
   649  
   650  func marshaltoPartialNesting_KitexFast(data []byte, exp *baseline.PartialNesting) error {
   651  	dataLen := len(data)
   652  	l := 0
   653  	for l < dataLen {
   654  		id, wtyp, tagLen := goprotowire.ConsumeTag(data)
   655  		if tagLen < 0 {
   656  			return errors.New("test failed")
   657  		}
   658  		l += tagLen
   659  		data = data[tagLen:]
   660  		offset, _ := exp.FastRead(data, int8(wtyp), int32(id))
   661  		data = data[offset:]
   662  		l += offset
   663  	}
   664  	data2 := make([]byte, exp.Size())
   665  	_ = exp.FastWrite(data2)
   666  	return nil
   667  }
   668  
   669  func BenchmarkProtoMarshalTo_KitexFast(b *testing.B) {
   670  	b.Run("small", func(b *testing.B) {
   671  		obj := getPbSimpleValue()
   672  		data := make([]byte, obj.Size())
   673  		ret := obj.FastWrite(data)
   674  		if ret != len(data) {
   675  			b.Fatal(ret)
   676  		}
   677  
   678  		// fast read check
   679  		exp := baseline.PartialSimple{}
   680  		dataLen := len(data)
   681  		l := 0
   682  		for l < dataLen {
   683  			id, wtyp, tagLen := goprotowire.ConsumeTag(data)
   684  			if tagLen < 0 {
   685  				b.Fatal("test failed")
   686  			}
   687  			l += tagLen
   688  			data = data[tagLen:]
   689  			offset, err := exp.FastRead(data, int8(wtyp), int32(id))
   690  			require.Nil(b, err)
   691  			data = data[offset:]
   692  			l += offset
   693  		}
   694  
   695  		data2 := make([]byte, exp.Size())
   696  		ret2 := exp.FastWrite(data2)
   697  		if ret2 != len(data2) {
   698  			b.Fatal(ret2)
   699  		}
   700  
   701  		data_obj := make([]byte, obj.Size()) 
   702  		ret = obj.FastWrite(data_obj)
   703  		if ret != len(data_obj) {
   704  			panic(ret)
   705  		}
   706  		b.SetBytes(int64(len(data)))
   707  		b.ResetTimer()
   708  		for i := 0; i < b.N; i++ {
   709  			exp := baseline.PartialSimple{}
   710  			_ = marshaltoPartialSimple_KitexFast(data_obj, &exp)
   711  		}
   712  	})
   713  
   714  	b.Run("medium", func(b *testing.B) {
   715  		obj := getPbNestingValue()
   716  		data := make([]byte, obj.Size()) 
   717  		ret := obj.FastWrite(data)
   718  		if ret != len(data) {
   719  			panic(ret)
   720  		}
   721  
   722  
   723  		// fast read check
   724  		exp := baseline.PartialNesting{}
   725  		dataLen := len(data)
   726  		l := 0
   727  		for l < dataLen {
   728  			id, wtyp, tagLen := goprotowire.ConsumeTag(data)
   729  			if tagLen < 0 {
   730  				b.Fatal("test failed")
   731  			}
   732  			l += tagLen
   733  			data = data[tagLen:]
   734  			offset, err := exp.FastRead(data, int8(wtyp), int32(id))
   735  			require.Nil(b, err)
   736  			data = data[offset:]
   737  			l += offset
   738  		}
   739  
   740  		data2 := make([]byte, exp.Size())
   741  		ret2 := exp.FastWrite(data2)
   742  		if ret2 != len(data2) {
   743  			b.Fatal(ret2)
   744  		}
   745  		
   746  		data_obj := make([]byte, obj.Size()) 
   747  		ret = obj.FastWrite(data_obj)
   748  		if ret != len(data_obj) {
   749  			panic(ret)
   750  		}
   751  		b.SetBytes(int64(len(data)))
   752  		b.ResetTimer()
   753  		for i := 0; i < b.N; i++ {
   754  			exp := baseline.PartialNesting{}
   755  			_ = marshaltoPartialNesting_KitexFast(data_obj, &exp)
   756  		}
   757  	})
   758  }
   759  
   760  // func BenchmarkProtoMarshalTo_ProtoBufGo(b *testing.B) {
   761  // 	b.Run("small", func(b *testing.B) {
   762  // 		obj := getPbSimpleValue()
   763  // 		data, err := goproto.Marshal(obj)
   764  // 		if err != nil {
   765  // 			b.Fatal(err)
   766  // 		}
   767  // 		part := &baseline.PartialSimple{}
   768  // 		opts := goproto.UnmarshalOptions{DiscardUnknown: true}
   769  // 		err = opts.Unmarshal(data, part)
   770  // 		if err != nil {
   771  // 			b.Fatal(err)
   772  // 		}
   773  
   774  // 		out, err2 := goproto.Marshal(part)
   775  // 		if err2 != nil {
   776  // 			b.Fatal(err2)
   777  // 		}
   778  		
   779  // 		desc := getPbSimpleDesc()
   780  // 		partdesc := getPbPartialSimpleDesc()
   781  // 		v := generic.NewRootValue(desc, data)
   782  // 		out2, err3 := v.MarshalTo(partdesc, &generic.Options{})
   783  // 		if err3 != nil {
   784  // 			b.Fatal(err3)
   785  // 		}
   786  
   787  // 		require.Equal(b, len(out), len(out2))
   788  
   789  // 		b.SetBytes(int64(len(data)))
   790  // 		b.ResetTimer()
   791  // 		for i := 0; i < b.N; i++ {
   792  // 			part := &baseline.PartialSimple{}
   793  // 			_ = opts.Unmarshal(data, part)
   794  // 			_, _ = goproto.Marshal(part)
   795  // 		}
   796  // 	})
   797  
   798  // 	b.Run("medium", func(b *testing.B) {
   799  // 		obj := getPbNestingValue()
   800  // 		data, err := goproto.Marshal(obj)
   801  // 		if err != nil {
   802  // 			b.Fatal(err)
   803  // 		}
   804  // 		part := &baseline.PartialNesting{}
   805  // 		opts := goproto.UnmarshalOptions{DiscardUnknown: true}
   806  // 		err = opts.Unmarshal(data, part)
   807  // 		if err != nil {
   808  // 			b.Fatal(err)
   809  // 		}
   810  
   811  // 		out, err2 := goproto.Marshal(part)
   812  // 		if err2 != nil {
   813  // 			b.Fatal(err2)
   814  // 		}
   815  
   816  // 		desc := getPbNestingDesc()
   817  // 		partdesc := getPbPartialNestingDesc()
   818  // 		v := generic.NewRootValue(desc, data)
   819  // 		out2, err3 := v.MarshalTo(partdesc, &generic.Options{})
   820  // 		if err3 != nil {
   821  // 			b.Fatal(err3)
   822  // 		}
   823  
   824  // 		require.Equal(b, len(out), len(out2))
   825  
   826  // 		b.SetBytes(int64(len(data)))
   827  // 		b.ResetTimer()
   828  // 		for i := 0; i < b.N; i++ {
   829  // 			part := &baseline.PartialNesting{}
   830  // 			_ = opts.Unmarshal(data, part)
   831  // 			_, _ = goproto.Marshal(part)
   832  // 		}
   833  // 	})
   834  // }
   835  
   836  /*
   837   * Marshal/Unmarshal test with ProtoBufGo, KitexFast, DynamicGo
   838   * 1. MarshalAll
   839   * 2. MarshalPartial
   840   * 3. UnmarshalAll
   841   * 4. UnmarshalPartial
   842   */
   843  
   844  // func BenchmarkProtoMarshalAll_ProtoBufGo(b *testing.B) {
   845  // 	b.Run("small", func(b *testing.B) {
   846  // 		obj := getPbSimpleValue()
   847  // 		data, err := goproto.Marshal(obj)
   848  // 		if err != nil {
   849  // 			b.Fatal(err)
   850  // 		}
   851  // 		b.SetBytes(int64(len(data)))
   852  // 		b.ResetTimer()
   853  // 		for i := 0; i < b.N; i++ {
   854  // 			_, _ = goproto.Marshal(obj)
   855  // 		}
   856  // 	})
   857  
   858  // 	b.Run("medium", func(b *testing.B) {
   859  // 		obj := getPbNestingValue()
   860  // 		data, err := goproto.Marshal(obj)
   861  // 		if err != nil {
   862  // 			b.Fatal(err)
   863  // 		}
   864  
   865  // 		b.SetBytes(int64(len(data)))
   866  // 		b.ResetTimer()
   867  // 		for i := 0; i < b.N; i++ {
   868  // 			_, _ = goproto.Marshal(obj)
   869  // 		}
   870  // 	})
   871  // }
   872  
   873  // func BenchmarkProtoMarshalPartial_ProtoBufGo(b *testing.B) {
   874  // 	b.Run("small", func(b *testing.B) {
   875  // 		obj := getPbPartialSimpleValue()
   876  // 		data, err := goproto.Marshal(obj)
   877  // 		if err != nil {
   878  // 			b.Fatal(err)
   879  // 		}
   880  // 		b.SetBytes(int64(len(data)))
   881  // 		b.ResetTimer()
   882  // 		for i := 0; i < b.N; i++ {
   883  // 			_, _ = goproto.Marshal(obj)
   884  // 		}
   885  // 	})
   886  
   887  // 	b.Run("medium", func(b *testing.B) {
   888  // 		obj := getPbPartialNestingValue()
   889  // 		data, err := goproto.Marshal(obj)
   890  // 		if err != nil {
   891  // 			b.Fatal(err)
   892  // 		}
   893  
   894  // 		b.SetBytes(int64(len(data)))
   895  // 		b.ResetTimer()
   896  // 		for i := 0; i < b.N; i++ {
   897  // 			_, _ = goproto.Marshal(obj)
   898  // 		}
   899  // 	})
   900  // }
   901  
   902  // func BenchmarkProtoUnmarshalAll_ProtoBufGo(b *testing.B) {
   903  // 	b.Run("small", func(b *testing.B) {
   904  // 		obj := getPbSimpleValue()
   905  // 		data, err := goproto.Marshal(obj)
   906  // 		if err != nil {
   907  // 			b.Fatal(err)
   908  // 		}
   909  // 		v := &baseline.Simple{}
   910  // 		b.SetBytes(int64(len(data)))
   911  // 		b.ResetTimer()
   912  // 		for i := 0; i < b.N; i++ {
   913  // 			_ = goproto.Unmarshal(data, v)
   914  // 		}
   915  // 	})
   916  
   917  // 	b.Run("medium", func(b *testing.B) {
   918  // 		obj := getPbNestingValue()
   919  // 		data, err := goproto.Marshal(obj)
   920  // 		if err != nil {
   921  // 			b.Fatal(err)
   922  // 		}
   923  // 		v := &baseline.Nesting{}
   924  // 		b.SetBytes(int64(len(data)))
   925  // 		b.ResetTimer()
   926  // 		for i := 0; i < b.N; i++ {
   927  // 			_ = goproto.Unmarshal(data, v)
   928  // 		}
   929  // 	})
   930  // }
   931  
   932  // func BenchmarkProtoUnmarshalPartial_ProtoBufGo(b *testing.B) {
   933  // 	b.Run("small", func(b *testing.B) {
   934  // 		obj := getPbPartialSimpleValue()
   935  // 		data, err := goproto.Marshal(obj)
   936  // 		if err != nil {
   937  // 			b.Fatal(err)
   938  // 		}
   939  // 		v := &baseline.PartialSimple{}
   940  // 		b.SetBytes(int64(len(data)))
   941  // 		b.ResetTimer()
   942  // 		for i := 0; i < b.N; i++ {
   943  // 			_ = goproto.Unmarshal(data, v)
   944  // 		}
   945  // 	})
   946  
   947  // 	b.Run("medium", func(b *testing.B) {
   948  // 		obj := getPbPartialNestingValue()
   949  // 		data, err := goproto.Marshal(obj)
   950  // 		if err != nil {
   951  // 			b.Fatal(err)
   952  // 		}
   953  // 		v := &baseline.PartialNesting{}
   954  // 		b.SetBytes(int64(len(data)))
   955  // 		b.ResetTimer()
   956  // 		for i := 0; i < b.N; i++ {
   957  // 			_ = goproto.Unmarshal(data, v)
   958  // 		}
   959  // 	})
   960  // }
   961  
   962  func BenchmarkProtoMarshalAll_KitexFast(b *testing.B) {
   963  	b.Run("small", func(b *testing.B) {
   964  		obj := getPbSimpleValue()
   965  		data := make([]byte, obj.Size())
   966  		ret := obj.FastWrite(data)
   967  		if ret != len(data) {
   968  			b.Fatal(ret)
   969  		}
   970  		b.SetBytes(int64(len(data)))
   971  		b.ResetTimer()
   972  		for i := 0; i < b.N; i++ {
   973  			result := data[:obj.Size()]
   974  			_ = obj.FastWrite(result)
   975  		}
   976  	})
   977  
   978  	b.Run("medium", func(b *testing.B) {
   979  		obj := getPbNestingValue()
   980  		data := make([]byte, obj.Size())
   981  		ret := obj.FastWrite(data)
   982  		if ret != len(data) {
   983  			b.Fatal(ret)
   984  		}
   985  		b.SetBytes(int64(len(data)))
   986  		b.ResetTimer()
   987  		for i := 0; i < b.N; i++ {
   988  			result := data[:obj.Size()]
   989  			_ = obj.FastWrite(result)
   990  		}
   991  	})
   992  }
   993  
   994  func BenchmarkProtoMarshalPartial_KitexFast(b *testing.B) {
   995  	b.Run("small", func(b *testing.B) {
   996  		obj := getPbPartialSimpleValue()
   997  		data := make([]byte, obj.Size())
   998  		ret := obj.FastWrite(data)
   999  		if ret != len(data) {
  1000  			b.Fatal(ret)
  1001  		}
  1002  
  1003  		b.SetBytes(int64(len(data)))
  1004  		result := make([]byte, obj.Size())
  1005  		b.ResetTimer()
  1006  		for i := 0; i < b.N; i++ {
  1007  			_ = obj.FastWrite(result)
  1008  		}
  1009  	})
  1010  
  1011  	b.Run("medium", func(b *testing.B) {
  1012  		obj := getPbPartialNestingValue()
  1013  		data := make([]byte, obj.Size())
  1014  		ret := obj.FastWrite(data)
  1015  		if ret != len(data) {
  1016  			b.Fatal(ret)
  1017  		}
  1018  
  1019  		b.SetBytes(int64(len(data)))
  1020  		result := make([]byte, obj.Size())
  1021  		b.ResetTimer()
  1022  		for i := 0; i < b.N; i++ {
  1023  			_ = obj.FastWrite(result)
  1024  		}
  1025  	})
  1026  }
  1027  
  1028  func readAllSimple(data []byte, exp *baseline.Simple) error {
  1029  	dataLen := len(data)
  1030  	l := 0
  1031  	for l < dataLen {
  1032  		id, wtyp, tagLen := goprotowire.ConsumeTag(data)
  1033  		if tagLen < 0 {
  1034  			return errors.New("test failed")
  1035  		}
  1036  		l += tagLen
  1037  		data = data[tagLen:]
  1038  		offset, err := exp.FastRead(data, int8(wtyp), int32(id))
  1039  		if err != nil {
  1040  			return err
  1041  		}
  1042  		data = data[offset:]
  1043  		l += offset
  1044  	}
  1045  	if len(data) != 0 {
  1046  		return errors.New("test failed")
  1047  	}
  1048  	return nil
  1049  }
  1050  
  1051  func readPartialSimple(data []byte, exp *baseline.PartialSimple) error {
  1052  	dataLen := len(data)
  1053  	l := 0
  1054  	for l < dataLen {
  1055  		id, wtyp, tagLen := goprotowire.ConsumeTag(data)
  1056  		if tagLen < 0 {
  1057  			return errors.New("test failed")
  1058  		}
  1059  		l += tagLen
  1060  		data = data[tagLen:]
  1061  		offset, err := exp.FastRead(data, int8(wtyp), int32(id))
  1062  		if err != nil {
  1063  			return err
  1064  		}
  1065  		data = data[offset:]
  1066  		l += offset
  1067  	}
  1068  	if len(data) != 0 {
  1069  		return errors.New("test failed")
  1070  	}
  1071  	return nil
  1072  }
  1073  
  1074  func readAllNesting(data []byte, exp *baseline.Nesting) error {
  1075  	dataLen := len(data)
  1076  	l := 0
  1077  	for l < dataLen {
  1078  		id, wtyp, tagLen := goprotowire.ConsumeTag(data)
  1079  		if tagLen < 0 {
  1080  			return errors.New("test failed")
  1081  		}
  1082  		l += tagLen
  1083  		data = data[tagLen:]
  1084  		offset, err := exp.FastRead(data, int8(wtyp), int32(id))
  1085  		if err != nil {
  1086  			return err
  1087  		}
  1088  		data = data[offset:]
  1089  		l += offset
  1090  	}
  1091  	if len(data) != 0 {
  1092  		return errors.New("test failed")
  1093  	}
  1094  	return nil
  1095  }
  1096  
  1097  func readPartialNesting(data []byte, exp *baseline.PartialNesting) error {
  1098  	dataLen := len(data)
  1099  	l := 0
  1100  	for l < dataLen {
  1101  		id, wtyp, tagLen := goprotowire.ConsumeTag(data)
  1102  		if tagLen < 0 {
  1103  			return errors.New("test failed")
  1104  		}
  1105  		l += tagLen
  1106  		data = data[tagLen:]
  1107  		offset, err := exp.FastRead(data, int8(wtyp), int32(id))
  1108  		if err != nil {
  1109  			return err
  1110  		}
  1111  		data = data[offset:]
  1112  		l += offset
  1113  	}
  1114  	if len(data) != 0 {
  1115  		return errors.New("test failed")
  1116  	}
  1117  	return nil
  1118  }
  1119  
  1120  func BenchmarkProtoUnmarshalAll_KitexFast(b *testing.B) {
  1121  	b.Run("small", func(b *testing.B) {
  1122  		obj := getPbSimpleValue()
  1123  		data := make([]byte, obj.Size())
  1124  		ret := obj.FastWrite(data)
  1125  		if ret != len(data) {
  1126  			b.Fatal(ret)
  1127  		}
  1128  
  1129  		exp := baseline.Simple{}
  1130  		err := readAllSimple(data, &exp)
  1131  		if err != nil {
  1132  			b.Fatal("read error")
  1133  		}
  1134  		require.Equal(b, *obj, exp)
  1135  
  1136  		b.SetBytes(int64(len(data)))
  1137  		b.ResetTimer()
  1138  		for i := 0; i < b.N; i++ {
  1139  			_ = readAllSimple(data, &baseline.Simple{})
  1140  		}
  1141  	})
  1142  
  1143  	b.Run("medium", func(b *testing.B) {
  1144  		obj := getPbNestingValue()
  1145  		data := make([]byte, obj.Size())
  1146  		ret := obj.FastWrite(data)
  1147  		if ret != len(data) {
  1148  			b.Fatal(ret)
  1149  		}
  1150  
  1151  		exp := baseline.Nesting{}
  1152  		err := readAllNesting(data, &exp)
  1153  		if err != nil {
  1154  			b.Fatal("read error")
  1155  		}
  1156  		require.Equal(b, *obj, exp)
  1157  
  1158  		b.SetBytes(int64(len(data)))
  1159  		b.ResetTimer()
  1160  		for i := 0; i < b.N; i++ {
  1161  			_ = readAllNesting(data, &baseline.Nesting{})
  1162  		}
  1163  	})
  1164  }
  1165  
  1166  func BenchmarkProtoUnmarshalPartial_KitexFast(b *testing.B) {
  1167  	b.Run("small", func(b *testing.B) {
  1168  		obj := getPbPartialSimpleValue()
  1169  		data := make([]byte, obj.Size())
  1170  		ret := obj.FastWrite(data)
  1171  		if ret != len(data) {
  1172  			b.Fatal(ret)
  1173  		}
  1174  
  1175  		exp := baseline.PartialSimple{}
  1176  		err := readPartialSimple(data, &exp)
  1177  		if err != nil {
  1178  			b.Fatal("read error")
  1179  		}
  1180  		require.Equal(b, *obj, exp)
  1181  
  1182  		b.SetBytes(int64(len(data)))
  1183  		b.ResetTimer()
  1184  		for i := 0; i < b.N; i++ {
  1185  			_ = readPartialSimple(data, &baseline.PartialSimple{})
  1186  		}
  1187  	})
  1188  
  1189  	b.Run("medium", func(b *testing.B) {
  1190  		obj := getPbPartialNestingValue()
  1191  		data := make([]byte, obj.Size())
  1192  		ret := obj.FastWrite(data)
  1193  		if ret != len(data) {
  1194  			b.Fatal(ret)
  1195  		}
  1196  		
  1197  		exp := baseline.PartialNesting{}
  1198  		err := readPartialNesting(data, &exp)
  1199  		if err != nil {
  1200  			b.Fatal("read error")
  1201  		}
  1202  		require.Equal(b, *obj, exp)
  1203  
  1204  		b.SetBytes(int64(len(data)))
  1205  		b.ResetTimer()
  1206  		for i := 0; i < b.N; i++ {
  1207  			_ = readPartialNesting(data, &baseline.PartialNesting{})
  1208  		}
  1209  	})
  1210  }
  1211  
  1212  func BenchmarkProtoMarshalAll_DynamicGo(b *testing.B) {
  1213  	b.Run("small", func(b *testing.B) {
  1214  		desc := getPbSimpleDesc()
  1215  		obj := getPbSimpleValue()
  1216  		data := make([]byte, obj.Size())
  1217  		ret := obj.FastWrite(data)
  1218  		if ret != len(data) {
  1219  			b.Fatal(ret)
  1220  		}
  1221  
  1222  		v := generic.NewRootValue(desc, data)
  1223  		p := generic.PathNode{
  1224  			Node: v.Node,
  1225  		}
  1226  		opts := &generic.Options{}
  1227  		require.Nil(b, p.Load(true, opts, desc))
  1228  		out, err := p.Marshal(opts)
  1229  		require.Nil(b, err)
  1230  		require.Equal(b, data, out)
  1231  
  1232  		b.SetBytes(int64(len(data)))
  1233  		b.ResetTimer()
  1234  		for i := 0; i < b.N; i++ {
  1235  			_, _ = p.Marshal(opts)
  1236  		}
  1237  	})
  1238  
  1239  	b.Run("medium", func(b *testing.B) {
  1240  		desc := getPbNestingDesc()
  1241  		obj := getPbNestingValue()
  1242  		data := make([]byte, obj.Size())
  1243  		ret := obj.FastWrite(data)
  1244  		if ret != len(data) {
  1245  			b.Fatal(ret)
  1246  		}
  1247  		v := generic.NewRootValue(desc, data)
  1248  		p := generic.PathNode{
  1249  			Node: v.Node,
  1250  		}
  1251  		opts := &generic.Options{}
  1252  		require.Nil(b, p.Load(true, opts, desc))
  1253  		out, err := p.Marshal(opts)
  1254  		require.Nil(b, err)
  1255  		require.Equal(b, data, out)
  1256  
  1257  		b.SetBytes(int64(len(data)))
  1258  		b.ResetTimer()
  1259  		for i := 0; i < b.N; i++ {
  1260  			_, _ = p.Marshal(opts)
  1261  		}
  1262  	})
  1263  }
  1264  
  1265  func BenchmarkProtoMarshalPartial_DynamicGo(b *testing.B) {
  1266  	b.Run("small", func(b *testing.B) {
  1267  		desc := getPbPartialSimpleDesc()
  1268  		obj := getPbPartialSimpleValue()
  1269  		data := make([]byte, obj.Size())
  1270  		ret := obj.FastWrite(data)
  1271  		if ret != len(data) {
  1272  			b.Fatal(ret)
  1273  		}
  1274  
  1275  		v := generic.NewRootValue(desc, data)
  1276  		p := generic.PathNode{
  1277  			Node: v.Node,
  1278  		}
  1279  		opts := &generic.Options{}
  1280  		require.Nil(b, p.Load(true, opts, desc))
  1281  		out, err := p.Marshal(opts)
  1282  		require.Nil(b, err)
  1283  		require.Equal(b, data, out)
  1284  
  1285  		b.SetBytes(int64(len(data)))
  1286  		b.ResetTimer()
  1287  		for i := 0; i < b.N; i++ {
  1288  			_, _ = p.Marshal(opts)
  1289  		}
  1290  	})
  1291  
  1292  	b.Run("medium", func(b *testing.B) {
  1293  		desc := getPbPartialNestingDesc()
  1294  		obj := getPbPartialNestingValue()
  1295  		data := make([]byte, obj.Size())
  1296  		ret := obj.FastWrite(data)
  1297  		if ret != len(data) {
  1298  			b.Fatal(ret)
  1299  		}
  1300  		v := generic.NewRootValue(desc, data)
  1301  		p := generic.PathNode{
  1302  			Node: v.Node,
  1303  		}
  1304  		opts := &generic.Options{}
  1305  		require.Nil(b, p.Load(true, opts, desc))
  1306  		out, err := p.Marshal(opts)
  1307  		require.Nil(b, err)
  1308  		require.Equal(b, data, out)
  1309  
  1310  		b.SetBytes(int64(len(data)))
  1311  		b.ResetTimer()
  1312  		for i := 0; i < b.N; i++ {
  1313  			_, _ = p.Marshal(opts)
  1314  		}
  1315  	})
  1316  }
  1317  
  1318  func BenchmarkProtoUnmarshalAllDynamicGoGet_New(b *testing.B) {
  1319  	b.Run("small", func(b *testing.B) {
  1320  		desc := getPbSimpleDesc()
  1321  		obj := getPbSimpleValue()
  1322  		data := make([]byte, obj.Size())
  1323  		ret := obj.FastWrite(data)
  1324  		if ret != len(data) {
  1325  			b.Fatal(ret)
  1326  		}
  1327  
  1328  		v := generic.NewRootValue(desc, data)
  1329  		out := []generic.PathNode{}
  1330  		require.Nil(b, v.Children(&out, false, &generic.Options{UseNativeSkip: false}, desc))
  1331  
  1332  		b.Run("go", func(b *testing.B) {
  1333  			opts := &generic.Options{
  1334  				UseNativeSkip: false,
  1335  				// OnlyScanStruct: true,
  1336  			}
  1337  			b.SetBytes(int64(len(data)))
  1338  			b.ResetTimer()
  1339  			for i := 0; i < b.N; i++ {
  1340  				out := []generic.PathNode{}
  1341  				_ = v.Children(&out, true, opts, desc)
  1342  			}
  1343  		})
  1344  	})
  1345  
  1346  	b.Run("medium", func(b *testing.B) {
  1347  		desc := getPbNestingDesc()
  1348  		obj := getPbNestingValue()
  1349  		data := make([]byte, obj.Size())
  1350  		ret := obj.FastWrite(data)
  1351  		if ret != len(data) {
  1352  			b.Fatal(ret)
  1353  		}
  1354  
  1355  		v := generic.NewRootValue(desc, data)
  1356  		out := []generic.PathNode{}
  1357  		require.Nil(b, v.Children(&out, false, &generic.Options{UseNativeSkip: false}, desc))
  1358  
  1359  		b.Run("go", func(b *testing.B) {
  1360  		opts := &generic.Options{
  1361  				UseNativeSkip: false,
  1362  			}
  1363  			b.SetBytes(int64(len(data)))
  1364  			b.ResetTimer()
  1365  			for i := 0; i < b.N; i++ {
  1366  				out := []generic.PathNode{}
  1367  				_ = v.Children(&out, true, opts, desc)
  1368  			}
  1369  		})
  1370  	})
  1371  }
  1372  
  1373  func BenchmarkProtoUnmarshalPartialDynamicGoGet_New(b *testing.B) {
  1374  	b.Run("small", func(b *testing.B) {
  1375  		desc := getPbPartialSimpleDesc()
  1376  		obj := getPbPartialSimpleValue()
  1377  		data := make([]byte, obj.Size())
  1378  		ret := obj.FastWrite(data)
  1379  		if ret != len(data) {
  1380  			b.Fatal(ret, len(data))
  1381  		}
  1382  
  1383  		v := generic.NewRootValue(desc, data)
  1384  		out := []generic.PathNode{}
  1385  		require.Nil(b, v.Children(&out, false, &generic.Options{UseNativeSkip: false}, desc))
  1386  
  1387  		b.Run("go", func(b *testing.B) {
  1388  			opts := &generic.Options{
  1389  				UseNativeSkip: false,
  1390  				// OnlyScanStruct: true,
  1391  			}
  1392  			b.SetBytes(int64(len(data)))
  1393  			b.ResetTimer()
  1394  			for i := 0; i < b.N; i++ {
  1395  				out := []generic.PathNode{}
  1396  				_ = v.Children(&out, true, opts, desc)
  1397  			}
  1398  		})
  1399  	})
  1400  
  1401  	b.Run("medium", func(b *testing.B) {
  1402  		desc := getPbPartialNestingDesc()
  1403  		obj := getPbPartialNestingValue()
  1404  		data := make([]byte, obj.Size())
  1405  		ret := obj.FastWrite(data)
  1406  		if ret != len(data) {
  1407  			b.Fatal(ret, len(data))
  1408  		}
  1409  
  1410  		v := generic.NewRootValue(desc, data)
  1411  		out := []generic.PathNode{}
  1412  		require.Nil(b, v.Children(&out, false, &generic.Options{UseNativeSkip: false}, desc))
  1413  
  1414  		b.Run("go", func(b *testing.B) {
  1415  			opts := &generic.Options{
  1416  				UseNativeSkip: false,
  1417  			}
  1418  			b.SetBytes(int64(len(data)))
  1419  			b.ResetTimer()
  1420  			for i := 0; i < b.N; i++ {
  1421  				out := []generic.PathNode{}
  1422  				_ = v.Children(&out, true, opts, desc)
  1423  			}
  1424  		})
  1425  	})
  1426  
  1427  }
  1428  
  1429  func BenchmarkProtoUnmarshalAllDynamicGoGet_ReuseMemory(b *testing.B) {
  1430  	b.Run("small", func(b *testing.B) {
  1431  		desc := getPbSimpleDesc()
  1432  		obj := getPbSimpleValue()
  1433  		data := make([]byte, obj.Size())
  1434  		ret := obj.FastWrite(data)
  1435  		if ret != len(data) {
  1436  			b.Fatal(ret, len(data))
  1437  		}
  1438  		v := generic.NewRootValue(desc, data)
  1439  		r := generic.NewPathNode()
  1440  		r.Node = v.Node
  1441  		r.Load(true, &generic.Options{UseNativeSkip: false}, desc)
  1442  		r.ResetAll()
  1443  		generic.FreePathNode(r)
  1444  
  1445  		b.Run("go", func(b *testing.B) {
  1446  			opts := &generic.Options{
  1447  				UseNativeSkip: false,
  1448  			}
  1449  			b.SetBytes(int64(len(data)))
  1450  			b.ResetTimer()
  1451  			for i := 0; i < b.N; i++ {
  1452  				r := generic.NewPathNode()
  1453  				r.Node = v.Node
  1454  				r.Load(true, opts, desc)
  1455  				r.ResetAll()
  1456  				generic.FreePathNode(r)
  1457  			}
  1458  		})
  1459  
  1460  	})
  1461  
  1462  	b.Run("medium", func(b *testing.B) {
  1463  		desc := getPbNestingDesc()
  1464  		obj := getPbNestingValue()
  1465  		data := make([]byte, obj.Size())
  1466  		ret := obj.FastWrite(data)
  1467  		if ret != len(data) {
  1468  			b.Fatal(ret, len(data))
  1469  		}
  1470  		v := generic.NewRootValue(desc, data)
  1471  		r := generic.NewPathNode()
  1472  		r.Node = v.Node
  1473  		r.Load(true, &generic.Options{UseNativeSkip: false}, desc)
  1474  		r.ResetAll()
  1475  		generic.FreePathNode(r)
  1476  
  1477  		b.Run("go", func(b *testing.B) {
  1478  			opts := &generic.Options{
  1479  				UseNativeSkip: false,
  1480  			}
  1481  			b.SetBytes(int64(len(data)))
  1482  			b.ResetTimer()
  1483  			for i := 0; i < b.N; i++ {
  1484  				r := generic.NewPathNode()
  1485  				r.Node = v.Node
  1486  				r.Load(true, opts, desc)
  1487  				r.ResetAll()
  1488  				generic.FreePathNode(r)
  1489  			}
  1490  		})
  1491  	})
  1492  }
  1493  
  1494  func BenchmarkProtoUnmarshalPartialDynamicGoGet_ReuseMemory(b *testing.B) {
  1495  	b.Run("small", func(b *testing.B) {
  1496  		desc := getPbPartialSimpleDesc()
  1497  		obj := getPbPartialSimpleValue()
  1498  		data := make([]byte, obj.Size())
  1499  		ret := obj.FastWrite(data)
  1500  		if ret != len(data) {
  1501  			b.Fatal(ret, len(data))
  1502  		}
  1503  		v := generic.NewRootValue(desc, data)
  1504  		r := generic.NewPathNode()
  1505  		r.Node = v.Node
  1506  		r.Load(true, &generic.Options{UseNativeSkip: false}, desc)
  1507  		r.ResetAll()
  1508  		generic.FreePathNode(r)
  1509  
  1510  		b.Run("go", func(b *testing.B) {
  1511  			opts := &generic.Options{
  1512  				UseNativeSkip: false,
  1513  			}
  1514  			b.SetBytes(int64(len(data)))
  1515  			b.ResetTimer()
  1516  			for i := 0; i < b.N; i++ {
  1517  				r := generic.NewPathNode()
  1518  				r.Node = v.Node
  1519  				r.Load(true, opts, desc)
  1520  				r.ResetAll()
  1521  				generic.FreePathNode(r)
  1522  			}
  1523  		})
  1524  
  1525  	})
  1526  
  1527  	b.Run("medium", func(b *testing.B) {
  1528  		desc := getPbPartialNestingDesc()
  1529  		obj := getPbPartialNestingValue()
  1530  		data := make([]byte, obj.Size())
  1531  		ret := obj.FastWrite(data)
  1532  		if ret != len(data) {
  1533  			b.Fatal(ret, len(data))
  1534  		}
  1535  		v := generic.NewRootValue(desc, data)
  1536  		r := generic.NewPathNode()
  1537  		r.Node = v.Node
  1538  		r.Load(true, &generic.Options{UseNativeSkip: false}, desc)
  1539  		r.ResetAll()
  1540  		generic.FreePathNode(r)
  1541  
  1542  		b.Run("go", func(b *testing.B) {
  1543  			opts := &generic.Options{
  1544  				UseNativeSkip: false,
  1545  			}
  1546  			b.SetBytes(int64(len(data)))
  1547  			b.ResetTimer()
  1548  			for i := 0; i < b.N; i++ {
  1549  				r := generic.NewPathNode()
  1550  				r.Node = v.Node
  1551  				r.Load(true, opts, desc)
  1552  				r.ResetAll()
  1553  				generic.FreePathNode(r)
  1554  			}
  1555  		})
  1556  	})
  1557  }
  1558  
  1559  /*
  1560   * Get/Set Fields RationTest in medium data, compared with ProtoBufGo
  1561   */
  1562  const (
  1563  	factor = 1.0 // change set/get field ratio
  1564  )
  1565  
  1566  func sizeNestingField(value reflect.Value, id int) int {
  1567  	name := fmt.Sprintf("%s%s", "SizeField", strconv.FormatInt(int64(id), 10))
  1568  	method := value.MethodByName(name)
  1569  	argument := []reflect.Value{}
  1570  	ans := method.Call(argument)
  1571  	return int(ans[0].Int())
  1572  }
  1573  
  1574  func encNestingField(value reflect.Value, id int, b []byte) error {
  1575  	name := fmt.Sprintf("%s%s", "FastWriteField", strconv.FormatInt(int64(id), 10))
  1576  	method := value.MethodByName(name)
  1577  	argument := []reflect.Value{reflect.ValueOf(b)}
  1578  	method.Call(argument)
  1579  	return nil
  1580  }
  1581  
  1582  func collectMarshalData(id int, value reflect.Value, b *[]byte) error {
  1583  	size := sizeNestingField(value, id)
  1584  	data := make([]byte, size)
  1585  	if err := encNestingField(value, id, data); err != nil {
  1586  		return err
  1587  	}
  1588  	*b = append(*b, data...)
  1589  	return nil
  1590  }
  1591  
  1592  func buildBinaryProtocolByFieldId(id int, p *binary.BinaryProtocol, value reflect.Value, desc *proto.FieldDescriptor) error {
  1593  	var err error
  1594  	size := sizeNestingField(value, id)
  1595  	data := make([]byte, size)
  1596  	if err = encNestingField(value, id, data); err != nil {
  1597  		return err
  1598  	}
  1599  	t := desc.Type()
  1600  	if !t.IsList() && !t.IsMap() {
  1601  		data = data[1:] // skip Tag because the test case tag len is 1, we just use 1, it is not always 1, please use comsumevarint
  1602  	}
  1603  	p.Buf = data
  1604  	return nil
  1605  }
  1606  
  1607  func BenchmarkRationGet_DynamicGo(b *testing.B) {
  1608  	b.Run("ration", func(b *testing.B) {
  1609  		desc := getPbNestingDesc()
  1610  		fieldNums := desc.Message().FieldsCount()
  1611  		obj := getPbNestingValue()
  1612  		data := make([]byte, obj.Size())
  1613  		ret := obj.FastWrite(data)
  1614  		if ret != len(data) {
  1615  			b.Fatal(ret)
  1616  		}
  1617  
  1618  		v := generic.NewRootValue(desc, data)
  1619  		testNums := int(math.Ceil(float64(fieldNums) * factor))
  1620  		value := reflect.ValueOf(obj)
  1621  		for id := 1; id <= testNums; id++ {
  1622  			vv := v.GetByPath(generic.NewPathFieldId(proto.FieldNumber(id)))
  1623  			require.Nil(b, vv.Check())
  1624  			size := sizeNestingField(value, id)
  1625  			data := make([]byte, size)
  1626  			if err := encNestingField(value, id, data); err != nil {
  1627  				b.Fatal("encNestingField failed, fieldId: {}", id)
  1628  			}
  1629  			// skip Tag
  1630  			t := vv.Node.Type()
  1631  			if t != proto.LIST && t != proto.MAP {
  1632  				data = data[1:] // skip Tag because the test case tag len is 1, we just use 1, it is not always 1, please use comsumevarint
  1633  			}
  1634  			vdata := vv.Raw()
  1635  			require.Equal(b, len(data), len(vdata))
  1636  		}
  1637  		b.ResetTimer()
  1638  		b.Run("go", func(b *testing.B) {
  1639  			for i := 0; i < b.N; i++ {
  1640  				option := generic.Options{}
  1641  				for id := 1; id <= testNums; id++ {
  1642  					vv := v.GetByPath(generic.NewPathFieldId(proto.FieldNumber(id)))
  1643  					vv.Interface(&option)
  1644  				}
  1645  			}
  1646  		})
  1647  	})
  1648  }
  1649  
  1650  // func BenchmarkRationGet_ProtobufGo(b *testing.B) {
  1651  // 	b.Run("ration", func(b *testing.B) {
  1652  // 		desc := getPbNestingDesc()
  1653  // 		fieldNums := (*desc).Fields().Len()
  1654  // 		obj := getPbNestingValue()
  1655  // 		data := make([]byte, obj.Size())
  1656  // 		ret := obj.FastWrite(data)
  1657  // 		if ret != len(data) {
  1658  // 			b.Fatal(ret)
  1659  // 		}
  1660  
  1661  // 		testNums := int(math.Ceil(float64(fieldNums) * factor))
  1662  // 		// build dynamicpb Message
  1663  // 		message := dynamicpb.NewMessage(*desc)
  1664  // 		if err := goproto.Unmarshal(data, message); err != nil {
  1665  // 			b.Fatal("build dynamicpb failed")
  1666  // 		}
  1667  // 		value := reflect.ValueOf(obj)
  1668  // 		for id := 1; id <= testNums; id++ {
  1669  // 			// dynamicpb read data
  1670  // 			targetDesc := (*desc).Fields().ByNumber(proto.FieldNumber(id))
  1671  // 			if !message.Has(targetDesc) {
  1672  // 				b.Fatal("dynamicpb can't find targetDesc")
  1673  // 			}
  1674  // 			_ = message.Get(targetDesc)
  1675  // 			// fastRead data
  1676  // 			size := sizeNestingField(value, id)
  1677  // 			data := make([]byte, size)
  1678  // 			if err := encNestingField(value, id, data); err != nil {
  1679  // 				b.Fatal("encNestingField failed, fieldId: {}", id)
  1680  // 			}
  1681  // 		}
  1682  // 		b.ResetTimer()
  1683  // 		b.Run("go", func(b *testing.B) {
  1684  // 			for i := 0; i < b.N; i++ {
  1685  // 				_ = goproto.Unmarshal(data, message)
  1686  // 				for id := 1; id <= testNums; id++ {
  1687  // 					targetDesc := (*desc).Fields().ByNumber(proto.FieldNumber(id))
  1688  // 					v := message.Get(targetDesc)
  1689  // 					v.Interface()
  1690  // 				}
  1691  // 			}
  1692  // 		})
  1693  // 	})
  1694  // }
  1695  
  1696  // deprecated
  1697  func BenchmarkProtoRationSetBefore(b *testing.B) {
  1698  	b.Run("ration", func(b *testing.B) {
  1699  		desc := getPbNestingDesc()
  1700  		fieldNums := desc.Message().FieldsCount()
  1701  		obj := getPbNestingValue()
  1702  		data := make([]byte, obj.Size())
  1703  		ret := obj.FastWrite(data)
  1704  		if ret != len(data) {
  1705  			b.Fatal(ret)
  1706  		}
  1707  
  1708  		v := generic.NewRootValue(desc, nil)
  1709  		opts := generic.Options{}
  1710  		ps := make([]generic.PathNode, 0)
  1711  		testNums := int(math.Ceil(float64(fieldNums) * factor))
  1712  		mObj := make([]byte, 0)
  1713  		value := reflect.ValueOf(obj)
  1714  		for id := 1; id <= testNums; id++ {
  1715  			p := binary.NewBinaryProtocolBuffer()
  1716  			fieldDesc := desc.Message().ByNumber(proto.FieldNumber(id))
  1717  			if err := collectMarshalData(id, value, &mObj); err != nil {
  1718  				b.Fatal("collect MarshalData failed")
  1719  			}
  1720  			if err := buildBinaryProtocolByFieldId(id, p, value, fieldDesc); err != nil {
  1721  				b.Fatal("build BinaryProtocolByFieldId failed")
  1722  			}
  1723  			field := desc.Message().ByNumber(proto.FieldNumber(id)).Type()
  1724  			n := generic.NewValue(field, p.Buf)
  1725  			_, err := v.SetByPath(n.Node, generic.NewPathFieldId(proto.FieldNumber(id)))
  1726  			require.Nil(b, err)
  1727  			nn := v.GetByPath(generic.NewPathFieldId(proto.FieldNumber(id)))
  1728  			nndata := nn.Raw()
  1729  			ndata := n.Raw()
  1730  			if nn.Type() != proto.MAP {
  1731  				require.Equal(b, nndata, ndata)
  1732  			} else {
  1733  				require.Equal(b, len(nndata), len(ndata))
  1734  			}
  1735  			pnode := generic.PathNode{
  1736  				Path: generic.NewPathFieldId(proto.FieldNumber(id)),
  1737  				Node: n.Node,
  1738  			}
  1739  			ps = append(ps, pnode)
  1740  			p.Recycle()
  1741  		}
  1742  		n := generic.PathNode{
  1743  			Path: generic.NewPathFieldId(1),
  1744  			Node: v.Node,
  1745  			Next: ps,
  1746  		}
  1747  		mProto, err := n.Marshal(&opts)
  1748  		if err != nil {
  1749  			b.Fatal("marshal PathNode failed")
  1750  		}
  1751  		require.Equal(b, len(mProto), len(mObj))
  1752  		b.SetBytes(int64(len(data)))
  1753  		b.ResetTimer()
  1754  		b.Run("go", func(b *testing.B) {
  1755  			for i := 0; i < b.N; i++ {
  1756  				opts := generic.Options{}
  1757  				v := generic.NewRootValue(desc, nil)
  1758  				ps := make([]generic.PathNode, 0)
  1759  				for id := 1; id <= testNums; id++ {
  1760  					p := binary.NewBinaryProtocolBuffer()
  1761  					fieldDesc := desc.Message().ByNumber(proto.FieldNumber(id))
  1762  					_ = buildBinaryProtocolByFieldId(id, p, value, fieldDesc)
  1763  					field := desc.Message().ByNumber(proto.FieldNumber(id)).Type()
  1764  					n := generic.NewValue(field, p.Buf)
  1765  					_, _ = v.SetByPath(n.Node, generic.NewPathFieldId(proto.FieldNumber(id)))
  1766  					pnode := generic.PathNode{
  1767  						Path: generic.NewPathFieldId(proto.FieldNumber(id)),
  1768  						Node: n.Node,
  1769  					}
  1770  					ps = append(ps, pnode)
  1771  					p.Recycle()
  1772  				}
  1773  				n := generic.PathNode{
  1774  					Path: generic.NewPathFieldId(1),
  1775  					Node: v.Node,
  1776  					Next: ps,
  1777  				}
  1778  				_, _ = n.Marshal(&opts)
  1779  			}
  1780  		})
  1781  	})
  1782  }
  1783  
  1784  
  1785  func BenchmarkRationSet_DynamicGo(b *testing.B) {
  1786  	b.Run("ration", func(b *testing.B) {
  1787  		desc := getPbNestingDesc()
  1788  		fieldNums := desc.Message().FieldsCount()
  1789  		obj := getPbNestingValue()
  1790  		data := make([]byte, obj.Size())
  1791  		ret := obj.FastWrite(data)
  1792  		if ret != len(data) {
  1793  			b.Fatal(ret)
  1794  		}
  1795  
  1796  		testNums := int(math.Ceil(float64(fieldNums) * factor))
  1797  		objRoot := generic.NewRootValue(desc, data)
  1798  		newRoot := generic.NewRootValue(desc, nil)
  1799  		ps := make([]generic.PathNode, 0)
  1800  		p := binary.NewBinaryProtocolBuffer()
  1801  		mObj := make([]byte, 0)
  1802  		value := reflect.ValueOf(obj)
  1803  		for id := 1; id <= testNums; id++ {
  1804  			if err := collectMarshalData(id, value, &mObj); err != nil {
  1805  				b.Fatal("collect MarshalData failed")
  1806  			}
  1807  			x := objRoot.GetByPath(generic.NewPathFieldId(proto.FieldNumber(id)))
  1808  			require.Nil(b, x.Check())
  1809  			m, err := x.Interface(&generic.Options{MapStructById: true})
  1810  			require.Nil(b, err)
  1811  			field := desc.Message().ByNumber(proto.FieldNumber(id)).Type()
  1812  			if field.IsMap() {
  1813  				err = p.WriteMap(field, m, true, false, false)
  1814  			} else if field.IsList() {
  1815  				err = p.WriteList(field, m, true, false, false)
  1816  			} else {
  1817  				// bacause basic type node buf no tag, just LV
  1818  				needMessageLen := true
  1819  				err = p.WriteBaseTypeWithDesc(field, m, needMessageLen, true, false, false)
  1820  			}
  1821  			// fmt.Println(id)
  1822  			require.Nil(b, err)
  1823  			newValue := generic.NewValue(field, p.Buf)
  1824  			if field.IsMap() || field.IsList() {
  1825  				newValue = generic.NewComplexValue(field, p.Buf)
  1826  			}
  1827  			// fmt.Println(id)
  1828  			require.Equal(b, len(newValue.Raw()), len(x.Raw()))
  1829  			_, err = newRoot.SetByPath(newValue.Node, generic.NewPathFieldId(proto.FieldNumber(id)))
  1830  			require.Nil(b, err)
  1831  			vv := newRoot.GetByPath(generic.NewPathFieldId(proto.FieldNumber(id)))
  1832  			require.Equal(b, len(newValue.Raw()), len(vv.Raw()))
  1833  			p.Recycle()
  1834  			ps = append(ps, generic.PathNode{ Path: generic.NewPathFieldId(proto.FieldNumber(id)), Node: newValue.Node })
  1835  		}
  1836  
  1837  		n := generic.PathNode{
  1838  			Path: generic.NewPathFieldId(1),
  1839  			Node: newRoot.Node,
  1840  			Next: ps,
  1841  		}
  1842  		mProto, err := n.Marshal(&generic.Options{})
  1843  		if err != nil {
  1844  			b.Fatal("marshal PathNode failed")
  1845  		}
  1846  		require.Equal(b, len(mProto), len(mObj))
  1847  
  1848  		b.SetBytes(int64(len(data)))
  1849  		b.ResetTimer()
  1850  		b.Run("go", func(b *testing.B) {
  1851  			for i := 0; i < b.N; i++ {
  1852  				objRoot := generic.NewRootValue(desc, data)
  1853  				newRoot := generic.NewRootValue(desc, nil)
  1854  				ps := make([]generic.PathNode, 0)
  1855  				p := binary.NewBinaryProtocolBuffer()
  1856  				opt := &generic.Options{MapStructById: true}
  1857  				for id := 1; id <= testNums; id++ {
  1858  					x := objRoot.GetByPath(generic.NewPathFieldId(proto.FieldNumber(id)))
  1859  					newValue := x.Fork()
  1860  					_, err = newRoot.SetByPath(newValue.Node, generic.NewPathFieldId(proto.FieldNumber(id)))
  1861  					p.Recycle()
  1862  					ps = append(ps, generic.PathNode{Path: generic.NewPathFieldId(proto.FieldNumber(id))})
  1863  				}
  1864  				_ = newRoot.GetMany(ps,opt)
  1865  				n := generic.PathNode{
  1866  					Path: generic.NewPathFieldId(1),
  1867  					Node: newRoot.Node,
  1868  					Next: ps,
  1869  				}
  1870  
  1871  				_, _ = n.Marshal(opt)
  1872  			}
  1873  		})
  1874  
  1875  	})
  1876  }
  1877  
  1878  func BenchmarkRationSetByInterface_DynamicGo(b *testing.B) {
  1879  	b.Run("ration", func(b *testing.B) {
  1880  		desc := getPbNestingDesc()
  1881  		fieldNums := desc.Message().FieldsCount()
  1882  		obj := getPbNestingValue()
  1883  		data := make([]byte, obj.Size())
  1884  		ret := obj.FastWrite(data)
  1885  		if ret != len(data) {
  1886  			b.Fatal(ret)
  1887  		}
  1888  
  1889  		testNums := int(math.Ceil(float64(fieldNums) * factor))
  1890  		objRoot := generic.NewRootValue(desc, data)
  1891  		newRoot := generic.NewRootValue(desc, nil)
  1892  		ps := make([]generic.PathNode, 0)
  1893  		p := binary.NewBinaryProtocolBuffer()
  1894  		mObj := make([]byte, 0)
  1895  		value := reflect.ValueOf(obj)
  1896  		for id := 1; id <= testNums; id++ {
  1897  			if err := collectMarshalData(id, value, &mObj); err != nil {
  1898  				b.Fatal("collect MarshalData failed")
  1899  			}
  1900  			x := objRoot.GetByPath(generic.NewPathFieldId(proto.FieldNumber(id)))
  1901  			require.Nil(b, x.Check())
  1902  			m, err := x.Interface(&generic.Options{MapStructById: true})
  1903  			require.Nil(b, err)
  1904  			field := desc.Message().ByNumber(proto.FieldNumber(id)).Type()
  1905  			if field.IsMap() {
  1906  				err = p.WriteMap(field, m, true, false, false)
  1907  			} else if field.IsList() {
  1908  				err = p.WriteList(field, m, true, false, false)
  1909  			} else {
  1910  				// bacause basic type node buf no tag, just LV
  1911  				needMessageLen := true
  1912  				err = p.WriteBaseTypeWithDesc(field, m, needMessageLen, true, false, false)
  1913  			}
  1914  			// fmt.Println(id)
  1915  			require.Nil(b, err)
  1916  			newValue := generic.NewValue(field, p.Buf)
  1917  			if field.IsMap() || field.IsList() {
  1918  				newValue = generic.NewComplexValue(field, p.Buf)
  1919  			}
  1920  			// fmt.Println(id)
  1921  			require.Equal(b, len(newValue.Raw()), len(x.Raw()))
  1922  			_, err = newRoot.SetByPath(newValue.Node, generic.NewPathFieldId(proto.FieldNumber(id)))
  1923  			require.Nil(b, err)
  1924  			vv := newRoot.GetByPath(generic.NewPathFieldId(proto.FieldNumber(id)))
  1925  			require.Equal(b, len(newValue.Raw()), len(vv.Raw()))
  1926  			p.Recycle()
  1927  			ps = append(ps, generic.PathNode{ Path: generic.NewPathFieldId(proto.FieldNumber(id)), Node: newValue.Node })
  1928  		}
  1929  
  1930  		n := generic.PathNode{
  1931  			Path: generic.NewPathFieldId(1),
  1932  			Node: newRoot.Node,
  1933  			Next: ps,
  1934  		}
  1935  		mProto, err := n.Marshal(&generic.Options{})
  1936  		if err != nil {
  1937  			b.Fatal("marshal PathNode failed")
  1938  		}
  1939  		require.Equal(b, len(mProto), len(mObj))
  1940  
  1941  		b.SetBytes(int64(len(data)))
  1942  		b.ResetTimer()
  1943  		b.Run("go", func(b *testing.B) {
  1944  			for i := 0; i < b.N; i++ {
  1945  				objRoot := generic.NewRootValue(desc, data)
  1946  				newRoot := generic.NewRootValue(desc, nil)
  1947  				ps := make([]generic.PathNode, 0)
  1948  				p := binary.NewBinaryProtocolBuffer()
  1949  				opt := &generic.Options{MapStructById: true}
  1950  				for id := 1; id <= testNums; id++ {
  1951  					x := objRoot.GetByPath(generic.NewPathFieldId(proto.FieldNumber(id)))
  1952  					m, _ := x.Interface(opt)
  1953  					field := desc.Message().ByNumber(proto.FieldNumber(id)).Type()
  1954  					if field.IsMap() {
  1955  						_ = p.WriteMap(field, m, true, false, false)
  1956  					} else if field.IsList() {
  1957  						_ = p.WriteList(field, m, true, false, false)
  1958  					} else {
  1959  						// bacause basic type node buf no tag, just LV
  1960  						needMessageLen := true
  1961  						_ = p.WriteBaseTypeWithDesc(field, m, needMessageLen, true, false, false)
  1962  					}
  1963  					newValue := generic.NewValue(field, p.Buf)
  1964  					// can not set when set complex value if use GetMany
  1965  					// if field.IsList() {
  1966  					// 	et := proto.FromProtoKindToType(field.Kind(), false, false)
  1967  					// 	newValue.SetElemType(et)
  1968  					// } else if field.IsMap() {
  1969  					// 	kt := proto.FromProtoKindToType(field.MapKey().Kind(), false, false)
  1970  					// 	newValue.SetKeyType(kt)
  1971  					// 	et := proto.FromProtoKindToType(field.MapValue().Kind(), false, false)
  1972  					// 	newValue.SetElemType(et)
  1973  					// }
  1974  					_, err = newRoot.SetByPath(newValue.Node, generic.NewPathFieldId(proto.FieldNumber(id)))
  1975  					p.Recycle()
  1976  					ps = append(ps, generic.PathNode{Path: generic.NewPathFieldId(proto.FieldNumber(id))})
  1977  				}
  1978  				_ = newRoot.GetMany(ps,opt)
  1979  				n := generic.PathNode{
  1980  					Path: generic.NewPathFieldId(1),
  1981  					Node: newRoot.Node,
  1982  					Next: ps,
  1983  				}
  1984  
  1985  				_, _ = n.Marshal(opt)
  1986  			}
  1987  		})
  1988  
  1989  	})
  1990  }
  1991  
  1992  func BenchmarkRationSetMany_DynamicGo(b *testing.B) {
  1993  	b.Run("ration", func(b *testing.B) {
  1994  		desc := getPbNestingDesc()
  1995  		fieldNums := desc.Message().FieldsCount()
  1996  		obj := getPbNestingValue()
  1997  		data := make([]byte, obj.Size())
  1998  		ret := obj.FastWrite(data)
  1999  		if ret != len(data) {
  2000  			b.Fatal(ret)
  2001  		}
  2002  		testNums := int(math.Ceil(float64(fieldNums) * factor))
  2003  		objRoot := generic.NewRootValue(desc, data)
  2004  		newRoot := generic.NewRootValue(desc, nil)
  2005  		ps := make([]generic.PathNode, testNums)
  2006  		opts := generic.Options{}
  2007  		mObj := make([]byte, 0)
  2008  		value := reflect.ValueOf(obj)
  2009  		
  2010  		for id := 1; id <= testNums; id++ {
  2011  			if err := collectMarshalData(id, value, &mObj); err != nil {
  2012  				b.Fatal("collect MarshalData failed")
  2013  			}
  2014  			ps[id-1] = generic.PathNode{Path: generic.NewPathFieldId(proto.FieldNumber(id))}
  2015  		}
  2016  		err := objRoot.GetMany(ps, &opts)
  2017  		if err != nil {
  2018  			b.Fatal("getMany failed")
  2019  		}
  2020  		adress2root := []int{}
  2021  		path2root := []generic.Path{}
  2022  		err = newRoot.SetMany(ps, &opts, &newRoot, adress2root, path2root...)
  2023  		if err != nil {
  2024  			b.Fatal("getMany failed")
  2025  		}
  2026  		err = newRoot.GetMany(ps, &generic.Options{ClearDirtyValues: true})
  2027  		if err != nil {
  2028  			b.Fatal("getMany failed")
  2029  		}
  2030  
  2031  		n := generic.PathNode{
  2032  			Path: generic.NewPathFieldId(1),
  2033  			Node: newRoot.Node,
  2034  			Next: ps,
  2035  		}
  2036  		mProto, err := n.Marshal(&generic.Options{})
  2037  		if err != nil {
  2038  			b.Fatal("marshal PathNode failed")
  2039  		}
  2040  		require.Equal(b, len(mProto), len(mObj))
  2041  		fmt.Println(len(mProto))
  2042  		b.SetBytes(int64(len(data)))
  2043  		b.ResetTimer()
  2044  		b.Run("go", func(b *testing.B) {
  2045  			for i := 0; i < b.N; i++ {
  2046  				objRoot := generic.NewRootValue(desc, data)
  2047  				newRoot := generic.NewRootValue(desc, nil)
  2048  				ps := make([]generic.PathNode, testNums)
  2049  				for id := 1; id <= testNums; id++ {
  2050  					ps[id-1] = generic.PathNode{Path: generic.NewPathFieldId(proto.FieldNumber(id))}
  2051  				}
  2052  				_ = objRoot.GetMany(ps, &opts)
  2053  				adress2root := make([]int, 0)
  2054  				path2root := make([]generic.Path, 0)
  2055  				newRoot.SetMany(ps, &opts, &newRoot, adress2root, path2root...)
  2056  				_ = newRoot.GetMany(ps, &generic.Options{ClearDirtyValues: true})
  2057  				n := generic.PathNode{
  2058  					Path: generic.NewPathFieldId(1),
  2059  					Node: newRoot.Node,
  2060  					Next: ps,
  2061  				}
  2062  				_, _ = n.Marshal(&generic.Options{})
  2063  				
  2064  			}
  2065  		})
  2066  	})
  2067  }
  2068  
  2069  // func BenchmarkRationSet_ProtobufGo(b *testing.B) {
  2070  // 	b.Run("ration", func(b *testing.B) {
  2071  // 		desc := getPbNestingDesc()
  2072  // 		fieldNums := (*desc).Fields().Len()
  2073  // 		obj := getPbNestingValue()
  2074  // 		data := make([]byte, obj.Size())
  2075  // 		ret := obj.FastWrite(data)
  2076  // 		if ret != len(data) {
  2077  // 			b.Fatal(ret)
  2078  // 		}
  2079  
  2080  // 		objMessage := dynamicpb.NewMessage(*desc)
  2081  // 		if err := goproto.Unmarshal(data, objMessage); err != nil {
  2082  // 			b.Fatal("build dynamicpb failed")
  2083  // 		}
  2084  
  2085  // 		testNums := int(math.Ceil(float64(fieldNums) * factor))
  2086  
  2087  // 		message := dynamicpb.NewMessage(*desc)
  2088  // 		for id := 1; id <= testNums; id++ {
  2089  // 			targetDesc := (*desc).Fields().ByNumber(proto.FieldNumber(id))
  2090  // 			fieldValue := objMessage.Get(targetDesc)
  2091  // 			v := fieldValue.Interface()
  2092  // 			newValue := protoreflect.ValueOf(v)
  2093  // 			message.Set(targetDesc, newValue)
  2094  // 		}
  2095  // 		out, err := goproto.Marshal(message)
  2096  // 		if err != nil {
  2097  // 			b.Fatal("Dynamicpb marshal failed")
  2098  // 		}
  2099  // 		fmt.Println(len(out))
  2100  // 		b.SetBytes(int64(len(data)))
  2101  // 		b.ResetTimer()
  2102  // 		b.Run("go", func(b *testing.B) {
  2103  // 			for i := 0; i < b.N; i++ {
  2104  // 				objMessage := dynamicpb.NewMessage(*desc)
  2105  // 				if err := goproto.Unmarshal(data, objMessage); err != nil {
  2106  // 					b.Fatal("build dynamicpb failed")
  2107  // 				}
  2108  // 				message := dynamicpb.NewMessage(*desc)
  2109  // 				for id := 1; id <= testNums; id++ {
  2110  // 					targetDesc := (*desc).Fields().ByNumber(proto.FieldNumber(id))
  2111  // 					fieldValue := objMessage.Get(targetDesc)
  2112  // 					message.Set(targetDesc, fieldValue)
  2113  // 				}
  2114  // 				_, _ = goproto.Marshal(message)
  2115  // 			}
  2116  // 		})
  2117  // 	})
  2118  // }
  2119  
  2120  // func BenchmarkRationSetByInterface_ProtobufGo(b *testing.B) {
  2121  // 	b.Run("ration", func(b *testing.B) {
  2122  // 		desc := getPbNestingDesc()
  2123  // 		fieldNums := (*desc).Fields().Len()
  2124  // 		obj := getPbNestingValue()
  2125  // 		data := make([]byte, obj.Size())
  2126  // 		ret := obj.FastWrite(data)
  2127  // 		if ret != len(data) {
  2128  // 			b.Fatal(ret)
  2129  // 		}
  2130  
  2131  // 		objMessage := dynamicpb.NewMessage(*desc)
  2132  // 		if err := goproto.Unmarshal(data, objMessage); err != nil {
  2133  // 			b.Fatal("build dynamicpb failed")
  2134  // 		}
  2135  
  2136  // 		testNums := int(math.Ceil(float64(fieldNums) * factor))
  2137  
  2138  // 		message := dynamicpb.NewMessage(*desc)
  2139  // 		for id := 1; id <= testNums; id++ {
  2140  // 			targetDesc := (*desc).Fields().ByNumber(proto.FieldNumber(id))
  2141  // 			fieldValue := objMessage.Get(targetDesc)
  2142  // 			v := fieldValue.Interface()
  2143  // 			newValue := protoreflect.ValueOf(v)
  2144  // 			message.Set(targetDesc, newValue)
  2145  // 		}
  2146  // 		out, err := goproto.Marshal(message)
  2147  // 		if err != nil {
  2148  // 			b.Fatal("Dynamicpb marshal failed")
  2149  // 		}
  2150  // 		fmt.Println(len(out))
  2151  // 		b.SetBytes(int64(len(data)))
  2152  // 		b.ResetTimer()
  2153  // 		b.Run("go", func(b *testing.B) {
  2154  // 			for i := 0; i < b.N; i++ {
  2155  // 				objMessage := dynamicpb.NewMessage(*desc)
  2156  // 				if err := goproto.Unmarshal(data, objMessage); err != nil {
  2157  // 					b.Fatal("build dynamicpb failed")
  2158  // 				}
  2159  // 				message := dynamicpb.NewMessage(*desc)
  2160  // 				for id := 1; id <= testNums; id++ {
  2161  // 					targetDesc := (*desc).Fields().ByNumber(proto.FieldNumber(id))
  2162  // 					fieldValue := objMessage.Get(targetDesc)
  2163  // 					v := fieldValue.Interface()
  2164  // 					newValue := protoreflect.ValueOf(v)
  2165  // 					message.Set(targetDesc, newValue)
  2166  // 				}
  2167  // 				_, _ = goproto.Marshal(message)
  2168  // 			}
  2169  // 		})
  2170  // 	})
  2171  // }
  2172