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

     1  /**
     2   * Copyright 2023 CloudWeGo Authors.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  //go:generate kitex -module=github.com/cloudwego/dynamicgo idl/baseline.thrift
    18  package testdata
    19  
    20  import (
    21  	"bytes"
    22  	"context"
    23  	"encoding/json"
    24  	ejson "encoding/json"
    25  	"sync"
    26  	"testing"
    27  
    28  	athrift "github.com/apache/thrift/lib/go/thrift"
    29  	"github.com/bytedance/sonic"
    30  	"github.com/cloudwego/dynamicgo/conv"
    31  	"github.com/cloudwego/dynamicgo/conv/t2j"
    32  	"github.com/cloudwego/dynamicgo/http"
    33  	"github.com/cloudwego/dynamicgo/testdata/kitex_gen/baseline"
    34  	"github.com/cloudwego/dynamicgo/thrift"
    35  	"github.com/cloudwego/kitex/pkg/generic"
    36  	gthrift "github.com/cloudwego/kitex/pkg/generic/thrift"
    37  	"github.com/stretchr/testify/require"
    38  )
    39  
    40  func getSimpleDesc() *thrift.TypeDescriptor {
    41  	svc, err := thrift.NewDescritorFromPath(context.Background(), idlPath)
    42  	if err != nil {
    43  		panic(err)
    44  	}
    45  	return svc.Functions()["SimpleMethod"].Request().Struct().FieldByKey("req").Type()
    46  }
    47  
    48  func getPartialSimpleDesc() *thrift.TypeDescriptor {
    49  	svc, err := thrift.NewDescritorFromPath(context.Background(), idlPath)
    50  	if err != nil {
    51  		panic(err)
    52  	}
    53  	return svc.Functions()["PartialSimpleMethod"].Request().Struct().FieldByKey("req").Type()
    54  }
    55  
    56  func getNestingDesc() *thrift.TypeDescriptor {
    57  	svc, err := thrift.NewDescritorFromPath(context.Background(), idlPath)
    58  	if err != nil {
    59  		panic(err)
    60  	}
    61  	return svc.Functions()["NestingMethod"].Request().Struct().FieldByKey("req").Type()
    62  }
    63  
    64  func getPartialNestingDesc() *thrift.TypeDescriptor {
    65  	svc, err := thrift.NewDescritorFromPath(context.Background(), idlPath)
    66  	if err != nil {
    67  		panic(err)
    68  	}
    69  	return svc.Functions()["PartialNestingMethod"].Request().Struct().FieldByKey("req").Type()
    70  }
    71  
    72  func TestThrift2JSON(t *testing.T) {
    73  	t.Run("small", func(t *testing.T) {
    74  		ctx := context.Background()
    75  		desc := getSimpleDesc()
    76  		data := getSimpleValue()
    77  		cv := t2j.NewBinaryConv(conv.Options{})
    78  		in := make([]byte, data.BLength())
    79  		if err := data.FastWriteNocopy(in, nil); err <= 0 {
    80  			t.Fatal(err)
    81  		}
    82  
    83  		ret, err := cv.Do(ctx, desc, in)
    84  		if err != nil {
    85  			t.Fatal(err)
    86  		}
    87  		// println(string(ret))
    88  		var v = baseline.NewSimple()
    89  		if err := ejson.Unmarshal(ret, v); err != nil {
    90  			t.Fatal(err)
    91  		}
    92  		require.Equal(t, data, v)
    93  	})
    94  	t.Run("medium", func(t *testing.T) {
    95  		ctx := context.Background()
    96  		desc := getNestingDesc()
    97  		data := getNestingValue()
    98  		cv := t2j.NewBinaryConv(conv.Options{})
    99  		in := make([]byte, data.BLength())
   100  		if err := data.FastWriteNocopy(in, nil); err <= 0 {
   101  			t.Fatal(err)
   102  		}
   103  
   104  		ret, err := cv.Do(ctx, desc, in)
   105  		if err != nil {
   106  			t.Fatal(err)
   107  		}
   108  		// println(string(ret))
   109  		var v = baseline.NewNesting()
   110  		if err := json.Unmarshal(ret, v); err != nil {
   111  			t.Fatal(err)
   112  		}
   113  		require.Equal(t, data, v)
   114  	})
   115  }
   116  
   117  func TestThrift2JSON_Parallel(t *testing.T) {
   118  	t.Run("small", func(t *testing.T) {
   119  		ctx := context.Background()
   120  		desc := getSimpleDesc()
   121  		data := getSimpleValue()
   122  		cv := t2j.NewBinaryConv(conv.Options{})
   123  		in := make([]byte, data.BLength())
   124  		if err := data.FastWriteNocopy(in, nil); err <= 0 {
   125  			t.Fatal(err)
   126  		}
   127  
   128  		wg := sync.WaitGroup{}
   129  		for i := 0; i < Concurrency; i++ {
   130  			wg.Add(1)
   131  			go func(i int) {
   132  				defer func() {
   133  					if r := recover(); r != nil {
   134  						t.Fatalf("panic: %d\n", i)
   135  					}
   136  				}()
   137  				defer wg.Done()
   138  
   139  				ret, err := cv.Do(ctx, desc, in)
   140  				if err != nil {
   141  					t.Fatal(err)
   142  				}
   143  				// println(string(ret))
   144  				var v = baseline.NewSimple()
   145  				if err := ejson.Unmarshal(ret, v); err != nil {
   146  					t.Fatal(err)
   147  				}
   148  				require.Equal(t, data, v)
   149  			}(i)
   150  		}
   151  		wg.Wait()
   152  	})
   153  	t.Run("medium", func(t *testing.T) {
   154  		ctx := context.Background()
   155  		desc := getNestingDesc()
   156  		data := getNestingValue()
   157  		cv := t2j.NewBinaryConv(conv.Options{})
   158  		in := make([]byte, data.BLength())
   159  		if err := data.FastWriteNocopy(in, nil); err <= 0 {
   160  			t.Fatal(err)
   161  		}
   162  
   163  		wg := sync.WaitGroup{}
   164  		for i := 0; i < Concurrency; i++ {
   165  			wg.Add(1)
   166  			go func(i int) {
   167  				defer func() {
   168  					if r := recover(); r != nil {
   169  						t.Fatalf("panic: %d\n", i)
   170  					}
   171  				}()
   172  				defer wg.Done()
   173  				ret, err := cv.Do(ctx, desc, in)
   174  				if err != nil {
   175  					t.Fatal(err)
   176  				}
   177  				// println(string(ret))
   178  				var v = baseline.NewNesting()
   179  				if err := json.Unmarshal(ret, v); err != nil {
   180  					t.Fatal(err)
   181  				}
   182  				require.Equal(t, data, v)
   183  			}(i)
   184  		}
   185  		wg.Wait()
   186  	})
   187  }
   188  
   189  func TestThrift2HTTP(t *testing.T) {
   190  	t.Run("small", func(t *testing.T) {
   191  		desc := getSimpleDesc()
   192  		data := getSimpleValue()
   193  		in := make([]byte, data.BLength())
   194  		if err := data.FastWriteNocopy(in, nil); err <= 0 {
   195  			t.Fatal(err)
   196  		}
   197  
   198  		opts := conv.Options{}
   199  		opts.EnableHttpMapping = true
   200  		opts.WriteHttpValueFallback = true
   201  		ctx := context.Background()
   202  		ctx = context.WithValue(ctx, conv.CtxKeyHTTPResponse, http.NewHTTPResponse())
   203  		cv := t2j.NewBinaryConv(opts)
   204  		out, err := cv.Do(ctx, desc, in)
   205  		if err != nil {
   206  			t.Fatal(err)
   207  		}
   208  
   209  		// resp := ctx.Value(conv.CtxKeyHTTPResponse).(*http.HTTPResponse)
   210  		// out, err := io.ReadAll(resp.Body)
   211  		// require.Nil(t, err)
   212  		var v = baseline.NewSimple()
   213  		if err := ejson.Unmarshal(out, v); err != nil {
   214  			t.Fatal(err)
   215  		}
   216  		require.Equal(t, data, v)
   217  
   218  		opts.EnableValueMapping = true
   219  		cv = t2j.NewBinaryConv(opts)
   220  		ret, err := cv.Do(ctx, desc, in)
   221  		if err != nil {
   222  			t.Fatal(err)
   223  		}
   224  		nr := convertStr2I64Simple(string(ret))
   225  		err = ejson.Unmarshal([]byte(nr), v)
   226  		require.Nil(t, err)
   227  	})
   228  
   229  	t.Run("medium", func(t *testing.T) {
   230  		desc := getNestingDesc()
   231  		data := getNestingValue()
   232  		in := make([]byte, data.BLength())
   233  		if err := data.FastWriteNocopy(in, nil); err <= 0 {
   234  			t.Fatal(err)
   235  		}
   236  
   237  		opts := conv.Options{}
   238  		opts.EnableHttpMapping = true
   239  		opts.WriteHttpValueFallback = true
   240  		opts.OmitHttpMappingErrors = true
   241  
   242  		ctx := context.Background()
   243  		resp := http.NewHTTPResponse()
   244  		ctx = context.WithValue(ctx, conv.CtxKeyHTTPResponse, resp)
   245  		cv := t2j.NewBinaryConv(opts)
   246  		out, err := cv.Do(ctx, desc, in)
   247  		if err != nil {
   248  			t.Fatal(err)
   249  		}
   250  		// out, err := io.ReadAll(resp.Body)
   251  		// require.Nil(t, err)
   252  		var v = baseline.NewNesting()
   253  		if err := json.Unmarshal(out, v); err != nil {
   254  			t.Fatal(err)
   255  		}
   256  		dstr := data.String_
   257  		data.String_ = ""
   258  		di32 := data.I32
   259  		data.I32 = 0
   260  		ls, err := json.Marshal(data.ListI64)
   261  		require.NoError(t, err)
   262  		data.ListI64 = nil
   263  		
   264  		require.Equal(t, data, v)
   265  		require.Equal(t, dstr, resp.Header.Get("String"))
   266  		require.Equal(t, int(di32), resp.StatusCode)
   267  		require.Equal(t, string(ls), resp.Cookies()[0].Value)
   268  
   269  		opts.EnableValueMapping = true
   270  		cv = t2j.NewBinaryConv(opts)
   271  		ret, err := cv.Do(ctx, desc, in)
   272  		if err != nil {
   273  			t.Fatal(err)
   274  		}
   275  		v = baseline.NewNesting()
   276  		ret = []byte(convertI642StringNesting(string(ret), false))
   277  		_ = ejson.Unmarshal(ret, v)
   278  		require.Equal(t, string(ls), resp.Cookies()[0].Value)
   279  		require.Equal(t, dstr, resp.Header.Get("String"))
   280  		require.Equal(t, int(di32), resp.StatusCode)
   281  	})
   282  }
   283  
   284  func TestThrift2HTTP_Parallel(t *testing.T) {
   285  	t.Run("small", func(t *testing.T) {
   286  		desc := getSimpleDesc()
   287  		opts := conv.Options{}
   288  		opts.EnableHttpMapping = true
   289  		opts.WriteHttpValueFallback = true
   290  		cv := t2j.NewBinaryConv(opts)
   291  
   292  		wg := sync.WaitGroup{}
   293  		for i := 0; i < Concurrency; i++ {
   294  			wg.Add(1)
   295  			go func(i int) {
   296  				defer func() {
   297  					if r := recover(); r != nil {
   298  						t.Fatalf("panic: %d\n", i)
   299  					}
   300  				}()
   301  				defer wg.Done()
   302  				data := getSimpleValue()
   303  				in := make([]byte, data.BLength())
   304  				if err := data.FastWriteNocopy(in, nil); err <= 0 {
   305  					t.Fatal(err)
   306  				}
   307  				ctx := context.Background()
   308  				ctx = context.WithValue(ctx, conv.CtxKeyHTTPResponse, http.NewHTTPResponse())
   309  				out, err := cv.Do(ctx, desc, in)
   310  				require.NoError(t, err)
   311  				var v = baseline.NewSimple()
   312  				if err := ejson.Unmarshal(out, v); err != nil {
   313  					t.Fatal(err)
   314  				}
   315  				require.Equal(t, data, v)
   316  			}(i)
   317  		}
   318  		wg.Wait()
   319  	})
   320  
   321  	t.Run("medium", func(t *testing.T) {
   322  		desc := getNestingDesc()
   323  		opts := conv.Options{}
   324  		opts.EnableHttpMapping = true
   325  		opts.WriteHttpValueFallback = true
   326  		opts.OmitHttpMappingErrors = true
   327  		cv := t2j.NewBinaryConv(opts)
   328  
   329  		wg := sync.WaitGroup{}
   330  		for i := 0; i < Concurrency; i++ {
   331  			wg.Add(1)
   332  			go func(i int) {
   333  				defer func() {
   334  					if r := recover(); r != nil {
   335  						t.Fatalf("panic: %d\n", i)
   336  					}
   337  				}()
   338  				defer wg.Done()
   339  				data := getNestingValue()
   340  				in := make([]byte, data.BLength())
   341  				if err := data.FastWriteNocopy(in, nil); err <= 0 {
   342  					t.Fatal(err)
   343  				}
   344  				ctx := context.Background()
   345  				resp := http.NewHTTPResponse()
   346  				ctx = context.WithValue(ctx, conv.CtxKeyHTTPResponse, resp)
   347  				out, err := cv.Do(ctx, desc, in)
   348  				if err != nil {
   349  					t.Fatal(err)
   350  				}
   351  				var v = baseline.NewNesting()
   352  				if err := json.Unmarshal(out, v); err != nil {
   353  					t.Fatal(err)
   354  				}
   355  				dstr := data.String_
   356  				data.String_ = ""
   357  				di32 := data.I32
   358  				data.I32 = 0
   359  				ls, err := json.Marshal(data.ListI64)
   360  				require.NoError(t, err)
   361  				data.ListI64 = nil
   362  				
   363  				require.Equal(t, data, v)
   364  				require.Equal(t, dstr, resp.Header.Get("String"))
   365  				require.Equal(t, int(di32), resp.StatusCode)
   366  				require.Equal(t, string(ls), resp.Cookies()[0].Value)
   367  			}(i)
   368  		}
   369  		wg.Wait()
   370  	})
   371  }
   372  
   373  func BenchmarkThrift2JSON_DynamicGo_Raw(b *testing.B) {
   374  	b.Run("small", func(b *testing.B) {
   375  		ctx := context.Background()
   376  		desc := getSimpleDesc()
   377  		cv := t2j.NewBinaryConv(conv.Options{})
   378  		data := getSimpleValue()
   379  		in := make([]byte, data.BLength())
   380  		if err := data.FastWriteNocopy(in, nil); err <= 0 {
   381  			b.Fatal(err)
   382  		}
   383  		_, err := cv.Do(ctx, desc, in)
   384  		if err != nil {
   385  			b.Fatal(err)
   386  		}
   387  		b.SetBytes(int64(len(in)))
   388  		b.ResetTimer()
   389  		for i := 0; i < b.N; i++ {
   390  			_, _ = cv.Do(ctx, desc, in)
   391  		}
   392  	})
   393  
   394  	b.Run("medium", func(b *testing.B) {
   395  		ctx := context.Background()
   396  		desc := getNestingDesc()
   397  		data := getNestingValue()
   398  		cv := t2j.NewBinaryConv(conv.Options{})
   399  		in := make([]byte, data.BLength())
   400  		if err := data.FastWriteNocopy(in, nil); err <= 0 {
   401  			b.Fatal(err)
   402  		}
   403  		_, err := cv.Do(ctx, desc, in)
   404  		if err != nil {
   405  			b.Fatal(err)
   406  		}
   407  		b.SetBytes(int64(len(in)))
   408  		b.ResetTimer()
   409  		for i := 0; i < b.N; i++ {
   410  			_, _ = cv.Do(ctx, desc, in)
   411  		}
   412  	})
   413  
   414  }
   415  
   416  func wrapKitexGenericRequestPayload(in []byte) []byte {
   417  	out := make([]byte, 0, len(in)+4)
   418  	p := thrift.NewBinaryProtocol(out)
   419  	p.WriteFieldBegin("", athrift.STRUCT, 1)
   420  	p.Buf = append(p.Buf, in...)
   421  	p.WriteFieldEnd()
   422  	p.WriteStructEnd()
   423  	return p.Buf
   424  }
   425  
   426  func wrapKitexGenericResponsePayload(in []byte) []byte {
   427  	out := make([]byte, 0, len(in)+4)
   428  	p := thrift.NewBinaryProtocol(out)
   429  	p.WriteFieldBegin("", athrift.STRUCT, 0)
   430  	p.Buf = append(p.Buf, in...)
   431  	p.WriteFieldEnd()
   432  	p.WriteStructEnd()
   433  	return p.Buf
   434  }
   435  
   436  func BenchmarkThrift2JSON_KitexGeneric(b *testing.B) {
   437  	p, err := generic.NewThriftFileProvider(idlPath)
   438  	if err != nil {
   439  		b.Fatal(err)
   440  	}
   441  	svcDsc := <-p.Provide()
   442  
   443  	b.Run("small", func(b *testing.B) {
   444  		codec := gthrift.NewReadJSON(svcDsc, false)
   445  		data := getSimpleValue()
   446  		in := make([]byte, data.BLength())
   447  		if err := data.FastWriteNocopy(in, nil); err <= 0 {
   448  			b.Fatal(err)
   449  		}
   450  		in = wrapKitexGenericRequestPayload(in)
   451  		var mm = athrift.NewStreamTransportR(bytes.NewBuffer(in))
   452  		bc := athrift.NewTBinaryProtocol(mm, false, false)
   453  		v, err := codec.Read(context.Background(), "SimpleMethod", bc)
   454  		if err != nil {
   455  			b.Fatal(err)
   456  		}
   457  		_ = v
   458  		// spew.Printf("%#+v\n", v)
   459  
   460  		b.SetBytes(int64(len(in)))
   461  		b.ResetTimer()
   462  		for i := 0; i < b.N; i++ {
   463  			var mm = athrift.NewStreamTransportR(bytes.NewBuffer(in))
   464  			bc := athrift.NewTBinaryProtocol(mm, false, false)
   465  			_, _ = codec.Read(context.Background(), "SimpleMethod", bc)
   466  		}
   467  	})
   468  
   469  	b.Run("medium", func(b *testing.B) {
   470  		codec := gthrift.NewReadJSON(svcDsc, false)
   471  		data := getNestingValue()
   472  		in := make([]byte, data.BLength())
   473  		if err := data.FastWriteNocopy(in, nil); err <= 0 {
   474  			b.Fatal(err)
   475  		}
   476  		in = wrapKitexGenericRequestPayload(in)
   477  		mm := athrift.NewStreamTransportR(bytes.NewBuffer(in))
   478  		bc := athrift.NewTBinaryProtocol(mm, false, false)
   479  		v, err := codec.Read(context.Background(), "NestingMethod", bc)
   480  		if err != nil {
   481  			b.Fatal(err)
   482  		}
   483  		_ = v
   484  		// spew.Printf("%#+v\n", v)
   485  
   486  		b.SetBytes(int64(len(in)))
   487  		b.ResetTimer()
   488  		for i := 0; i < b.N; i++ {
   489  			mm = athrift.NewStreamTransportR(bytes.NewBuffer(in))
   490  			bc = athrift.NewTBinaryProtocol(mm, false, false)
   491  			_, _ = codec.Read(context.Background(), "NestingMethod", bc)
   492  		}
   493  	})
   494  }
   495  
   496  func BenchmarkThrift2JSON_SonicAndKitex(b *testing.B) {
   497  	b.Run("small", func(b *testing.B) {
   498  		v := getSimpleValue()
   499  		var buf = make([]byte, v.BLength())
   500  		if err := v.FastWriteNocopy(buf, nil); err <= 0 {
   501  			b.Fatal(err)
   502  		}
   503  
   504  		obj := baseline.NewSimple()
   505  		_, err := obj.FastRead(buf)
   506  		if err != nil {
   507  			b.Fatal(err)
   508  		}
   509  		_, err = sonic.Marshal(obj)
   510  		if err != nil {
   511  			b.Fatal(err)
   512  		}
   513  		// println(string(out))
   514  
   515  		b.SetBytes(int64(len(buf)))
   516  		b.ResetTimer()
   517  		for i := 0; i < b.N; i++ {
   518  			obj := baseline.NewSimple()
   519  			_, _ = obj.FastRead(buf)
   520  			_, _ = sonic.Marshal(obj)
   521  		}
   522  	})
   523  
   524  	b.Run("medium", func(b *testing.B) {
   525  		v := getNestingValue()
   526  		var buf = make([]byte, v.BLength())
   527  		if err := v.FastWriteNocopy(buf, nil); err <= 0 {
   528  			b.Fatal(err)
   529  		}
   530  
   531  		obj := baseline.NewNesting()
   532  		_, err := obj.FastRead(buf)
   533  		if err != nil {
   534  			b.Fatal(err)
   535  		}
   536  		_, err = sonic.Marshal(obj)
   537  		if err != nil {
   538  			b.Fatal(err)
   539  		}
   540  		// println(string(out))
   541  
   542  		b.SetBytes(int64(len(buf)))
   543  		b.ResetTimer()
   544  		for i := 0; i < b.N; i++ {
   545  			obj := baseline.NewNesting()
   546  			_, _ = obj.FastRead(buf)
   547  			_, _ = sonic.Marshal(obj)
   548  		}
   549  	})
   550  }
   551  
   552  func BenchmarkThrift2HTTP_DynamicGo(t *testing.B) {
   553  	t.Run("small/value_mapping", func(t *testing.B) {
   554  		desc := getSimpleDesc()
   555  		data := getSimpleValue()
   556  		in := make([]byte, data.BLength())
   557  		if err := data.FastWriteNocopy(in, nil); err <= 0 {
   558  			t.Fatal(err)
   559  		}
   560  
   561  		opts := conv.Options{}
   562  		opts.EnableValueMapping = false
   563  		opts.OmitHttpMappingErrors = true
   564  		ctx := context.Background()
   565  		ctx = context.WithValue(ctx, conv.CtxKeyHTTPResponse, http.NewHTTPResponse())
   566  		cv := t2j.NewBinaryConv(opts)
   567  		ret, err := cv.Do(ctx, desc, in)
   568  		if err != nil {
   569  			t.Fatal(err)
   570  		}
   571  		ret = []byte(convertStr2I64Simple(string(ret)))
   572  		if err := ejson.Unmarshal(ret, baseline.NewSimple()); err != nil {
   573  			t.Fatal(err)
   574  		}
   575  
   576  		t.SetBytes(int64(len(in)))
   577  		t.ResetTimer()
   578  		for i := 0; i < t.N; i++ {
   579  			_, err = cv.Do(ctx, desc, in)
   580  		}
   581  	})
   582  
   583  	t.Run("medium/http_mapping", func(t *testing.B) {
   584  		desc := getNestingDesc()
   585  		data := getNestingValue()
   586  		in := make([]byte, data.BLength())
   587  		if err := data.FastWriteNocopy(in, nil); err <= 0 {
   588  			t.Fatal(err)
   589  		}
   590  
   591  		opts := conv.Options{}
   592  		opts.EnableHttpMapping = true
   593  		opts.EnableValueMapping = false
   594  		opts.OmitHttpMappingErrors = true
   595  		opts.NoCopyString = true
   596  
   597  		ctx := context.Background()
   598  		resp := http.NewHTTPResponse()
   599  		ctx = context.WithValue(ctx, conv.CtxKeyHTTPResponse, resp)
   600  		cv := t2j.NewBinaryConv(opts)
   601  		ret, err := cv.Do(ctx, desc, in)
   602  		if err != nil {
   603  			t.Fatal(err)
   604  		}
   605  		if err := ejson.Unmarshal(ret, baseline.NewNesting()); err != nil {
   606  			t.Fatal(err)
   607  		}
   608  
   609  		t.SetBytes(int64(len(in)))
   610  		t.ResetTimer()
   611  		for i := 0; i < t.N; i++ {
   612  			_, err = cv.Do(ctx, desc, in)
   613  		}
   614  	})
   615  
   616  	t.Run("medium/http+value_mapping", func(t *testing.B) {
   617  		desc := getNestingDesc()
   618  		data := getNestingValue()
   619  		in := make([]byte, data.BLength())
   620  		if err := data.FastWriteNocopy(in, nil); err <= 0 {
   621  			t.Fatal(err)
   622  		}
   623  
   624  		opts := conv.Options{}
   625  		opts.EnableHttpMapping = true
   626  		opts.EnableValueMapping = true
   627  		opts.OmitHttpMappingErrors = true
   628  		opts.NoCopyString = true
   629  
   630  		ctx := context.Background()
   631  		resp := http.NewHTTPResponse()
   632  		ctx = context.WithValue(ctx, conv.CtxKeyHTTPResponse, resp)
   633  		cv := t2j.NewBinaryConv(opts)
   634  		ret, err := cv.Do(ctx, desc, in)
   635  		if err != nil {
   636  			t.Fatal(err)
   637  		}
   638  		ret = []byte(convertI642StringNesting(string(ret), false))
   639  		if err := ejson.Unmarshal(ret, baseline.NewNesting()); err != nil {
   640  			t.Fatal(err)
   641  		}
   642  
   643  		t.SetBytes(int64(len(in)))
   644  		t.ResetTimer()
   645  		for i := 0; i < t.N; i++ {
   646  			_, err = cv.Do(ctx, desc, in)
   647  		}
   648  	})
   649  }
   650  
   651  func BenchmarkThrift2HTTP_KitexGeneric(b *testing.B) {
   652  	p, err := generic.NewThriftFileProvider(idlPath)
   653  	if err != nil {
   654  		b.Fatal(err)
   655  	}
   656  	svcDsc := <-p.Provide()
   657  
   658  	b.Run("small/http+value_mapping", func(b *testing.B) {
   659  		codec := gthrift.NewReadHTTPResponse(svcDsc)
   660  		data := getSimpleValue()
   661  		in := make([]byte, data.BLength())
   662  		if err := data.FastWriteNocopy(in, nil); err <= 0 {
   663  			b.Fatal(err)
   664  		}
   665  		in = wrapKitexGenericResponsePayload(in)
   666  		var mm = athrift.NewStreamTransportR(bytes.NewBuffer(in))
   667  		bc := athrift.NewTBinaryProtocol(mm, false, false)
   668  		v, err := codec.Read(context.Background(), "SimpleMethod", bc)
   669  		if err != nil {
   670  			b.Fatal(err)
   671  		}
   672  		_ = v
   673  		// spew.Printf("%#+v\n", v)
   674  
   675  		b.SetBytes(int64(len(in)))
   676  		b.ResetTimer()
   677  		for i := 0; i < b.N; i++ {
   678  			var mm = athrift.NewStreamTransportR(bytes.NewBuffer(in))
   679  			bc := athrift.NewTBinaryProtocol(mm, false, false)
   680  			_, _ = codec.Read(context.Background(), "SimpleMethod", bc)
   681  		}
   682  	})
   683  
   684  	b.Run("medium/http+value_mapping", func(b *testing.B) {
   685  		codec := gthrift.NewReadHTTPResponse(svcDsc)
   686  		data := getNestingValue()
   687  		in := make([]byte, data.BLength())
   688  		if err := data.FastWriteNocopy(in, nil); err <= 0 {
   689  			b.Fatal(err)
   690  		}
   691  		in = wrapKitexGenericResponsePayload(in)
   692  		mm := athrift.NewStreamTransportR(bytes.NewBuffer(in))
   693  		bc := athrift.NewTBinaryProtocol(mm, false, false)
   694  		v, err := codec.Read(context.Background(), "NestingMethod", bc)
   695  		if err != nil {
   696  			b.Fatal(err)
   697  		}
   698  		_ = v
   699  		// spew.Printf("%#+v\n", v)
   700  
   701  		b.SetBytes(int64(len(in)))
   702  		b.ResetTimer()
   703  		for i := 0; i < b.N; i++ {
   704  			mm = athrift.NewStreamTransportR(bytes.NewBuffer(in))
   705  			bc = athrift.NewTBinaryProtocol(mm, false, false)
   706  			_, _ = codec.Read(context.Background(), "NestingMethod", bc)
   707  		}
   708  	})
   709  }