github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/testdata/baseline_j2t_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 ejson "encoding/json" 24 "math" 25 stdh "net/http" 26 "strconv" 27 "strings" 28 "sync" 29 "testing" 30 31 athrift "github.com/apache/thrift/lib/go/thrift" 32 "github.com/bytedance/sonic" 33 json "github.com/bytedance/sonic/ast" 34 "github.com/cloudwego/dynamicgo/conv" 35 "github.com/cloudwego/dynamicgo/conv/j2t" 36 "github.com/cloudwego/dynamicgo/http" 37 "github.com/cloudwego/dynamicgo/testdata/kitex_gen/baseline" 38 "github.com/cloudwego/kitex/pkg/generic" 39 "github.com/cloudwego/kitex/pkg/generic/descriptor" 40 gthrift "github.com/cloudwego/kitex/pkg/generic/thrift" 41 "github.com/cloudwego/kitex/pkg/remote" 42 bthrift "github.com/cloudwego/kitex/pkg/remote/codec/thrift" 43 "github.com/stretchr/testify/require" 44 ) 45 46 const ( 47 idlPath = "idl/baseline.thrift" 48 ) 49 50 var ( 51 simpleJSON = "" 52 nestingJSON = "" 53 ) 54 55 func init() { 56 sobj := getSimpleValue() 57 sout, err := ejson.Marshal(sobj) 58 if err != nil { 59 panic(err) 60 } 61 simpleJSON = string(sout) 62 println("small data size: ", len(simpleJSON)) 63 var out bytes.Buffer 64 ejson.Indent(&out, sout, "", "") 65 println(out.String()) 66 67 nobj := getNestingValue() 68 nout, err := ejson.Marshal(nobj) 69 if err != nil { 70 panic(err) 71 } 72 nestingJSON = string(nout) 73 println("medium data size: ", len(nestingJSON)) 74 out.Reset() 75 76 psobj := getPartialSimpleValue() 77 psout, err := ejson.Marshal(psobj) 78 if err != nil { 79 panic(err) 80 } 81 println("partial small data size: ", len(psout)) 82 83 pnobj := getPartialNestingValue() 84 pnout, err := ejson.Marshal(pnobj) 85 if err != nil { 86 panic(err) 87 } 88 println("partial medium data size: ", len(pnout)) 89 } 90 91 type Sample struct { 92 name string 93 val interface{} 94 bytes []byte 95 } 96 97 var samples []Sample 98 99 var ( 100 bytesCount int = 2 101 stringCount int = 2 102 listCount int = 16 103 mapCount int = 16 104 ) 105 106 func getSamples() []Sample { 107 return []Sample{ 108 {samples[0].name, getSimpleValue(), samples[0].bytes}, 109 {samples[1].name, getNestingValue(), samples[1].bytes}, 110 {samples[2].name, getNesting2Value(), samples[2].bytes}, 111 } 112 } 113 114 func getString() string { 115 return strings.Repeat("你好,\b\n\r\t世界", stringCount) 116 } 117 118 func getBytes() []byte { 119 return bytes.Repeat([]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, bytesCount) 120 } 121 122 func getSimpleValue() *baseline.Simple { 123 return &baseline.Simple{ 124 ByteField: math.MaxInt8, 125 I64Field: math.MaxInt64, 126 DoubleField: math.MaxFloat64, 127 I32Field: math.MaxInt32, 128 StringField: getString(), 129 BinaryField: getBytes(), 130 } 131 } 132 133 func getPartialSimpleValue() *baseline.PartialSimple { 134 return &baseline.PartialSimple{ 135 ByteField: math.MaxInt8, 136 DoubleField: math.MaxFloat64, 137 BinaryField: getBytes(), 138 } 139 } 140 141 func getNestingValue() *baseline.Nesting { 142 var ret = &baseline.Nesting{ 143 String_: getString(), 144 ListSimple: []*baseline.Simple{}, 145 Double: math.MaxFloat64, 146 I32: math.MaxInt32, 147 ListI32: []int32{}, 148 I64: math.MaxInt64, 149 MapStringString: map[string]string{}, 150 SimpleStruct: getSimpleValue(), 151 MapI32I64: map[int32]int64{}, 152 ListString: []string{}, 153 Binary: getBytes(), 154 MapI64String: map[int64]string{}, 155 ListI64: []int64{}, 156 Byte: math.MaxInt8, 157 MapStringSimple: map[string]*baseline.Simple{}, 158 } 159 160 for i := 0; i < listCount; i++ { 161 ret.ListSimple = append(ret.ListSimple, getSimpleValue()) 162 ret.ListI32 = append(ret.ListI32, math.MinInt32) 163 ret.ListI64 = append(ret.ListI64, math.MinInt64) 164 ret.ListString = append(ret.ListString, getString()) 165 } 166 167 for i := 0; i < mapCount; i++ { 168 ret.MapStringString[strconv.Itoa(i)] = getString() 169 ret.MapI32I64[int32(i)] = math.MinInt64 170 ret.MapI64String[int64(i)] = getString() 171 ret.MapStringSimple[strconv.Itoa(i)] = getSimpleValue() 172 } 173 174 return ret 175 } 176 177 func getPartialNestingValue() *baseline.PartialNesting { 178 var ret = &baseline.PartialNesting{ 179 ListSimple: []*baseline.PartialSimple{}, 180 SimpleStruct: getPartialSimpleValue(), 181 MapStringSimple: map[string]*baseline.PartialSimple{}, 182 } 183 184 for i := 0; i < listCount; i++ { 185 ret.ListSimple = append(ret.ListSimple, getPartialSimpleValue()) 186 } 187 188 for i := 0; i < mapCount; i++ { 189 ret.MapStringSimple[strconv.Itoa(i)] = getPartialSimpleValue() 190 } 191 192 return ret 193 } 194 195 func getNesting2Value() *baseline.Nesting2 { 196 var ret = &baseline.Nesting2{ 197 MapSimpleNesting: map[*baseline.Simple]*baseline.Nesting{}, 198 SimpleStruct: getSimpleValue(), 199 Byte: math.MaxInt8, 200 Double: math.MaxFloat64, 201 ListNesting: []*baseline.Nesting{}, 202 I64: math.MaxInt64, 203 NestingStruct: getNestingValue(), 204 Binary: getBytes(), 205 String_: getString(), 206 SetNesting: []*baseline.Nesting{}, 207 I32: math.MaxInt32, 208 } 209 for i := 0; i < mapCount; i++ { 210 ret.MapSimpleNesting[getSimpleValue()] = getNestingValue() 211 } 212 for i := 0; i < listCount; i++ { 213 ret.ListNesting = append(ret.ListNesting, getNestingValue()) 214 x := getNestingValue() 215 x.I64 = int64(i) 216 ret.SetNesting = append(ret.SetNesting, x) 217 } 218 return ret 219 } 220 221 func getSampleHttpRequest(exp *baseline.Nesting, jbody string) *http.HTTPRequest { 222 req := http.NewHTTPRequest() 223 hr, err := stdh.NewRequest("POST", "localhost:8080", bytes.NewBufferString(jbody)) 224 if err != nil { 225 panic(err) 226 } 227 hr.Header.Set("Content-Type", "application/json") 228 req.Request = hr 229 header := "你好" 230 req.Request.Header.Set("String", header) 231 exp.String_ = header 232 // h2 := "abcdefghijklmnopqrstuvwxyz" 233 // req.Header.Set("string_field", h2) 234 // exp.SimpleStruct.StringField = h2 235 // for i := range exp.ListSimple { 236 // exp.ListSimple[i].StringField = h2 237 // } 238 // for k := range exp.MapStringSimple { 239 // exp.MapStringSimple[k].StringField = h2 240 // } 241 242 c := []int64{-1, 0, math.MaxInt64, math.MinInt64} 243 cookie := "" 244 for i, v := range c { 245 cookie += strconv.Itoa(int(v)) 246 if i != len(c)-1 { 247 cookie += "," 248 } 249 } 250 req.AddCookie(&stdh.Cookie{ 251 Name: "list_i64", 252 Value: cookie, 253 }) 254 exp.ListI64 = c 255 256 param := math.MaxFloat64 257 req.Params.Set("double", strconv.FormatFloat(param, 'f', -1, 64)) 258 exp.Double = param 259 260 q := []int32{-1, 0, math.MaxInt32, math.MinInt32} 261 query := "" 262 for i, v := range q { 263 query += strconv.Itoa(int(v)) 264 if i != len(q)-1 { 265 query += "," 266 } 267 } 268 req.Request.URL.RawQuery = "ListI32=" + query 269 exp.ListI32 = q 270 return req 271 } 272 273 func getSampleHttpResponse(exp *baseline.Nesting) *http.HTTPResponse { 274 req := http.NewHTTPResponse() 275 276 code := int32(401) 277 req.StatusCode = int(code) 278 exp.I32 = code 279 280 header := "你好" 281 req.Header.Set("String", header) 282 exp.String_ = header 283 284 c := []int64{-1, 0, math.MaxInt64, math.MinInt64} 285 cookie := "" 286 for i, v := range c { 287 cookie += strconv.Itoa(int(v)) 288 if i != len(c)-1 { 289 cookie += "," 290 } 291 } 292 req.SetCookie("list_i64", cookie) 293 exp.ListI64 = c 294 return req 295 } 296 297 // func TestThriftEncodeSimple_Load(t *testing.T) { 298 // _, err := ejson.Marshal(baseline.Simple{}) 299 // if err != nil { 300 // t.Fatal(err) 301 // } 302 // simple := getSimpleDesc() 303 // // fmt.Printf("%#v", simple) 304 // root, err := json.NewSearcher(simpleJSON).GetByPath() 305 // if err != nil { 306 // t.Fatal(err) 307 // } 308 // if err := root.LoadAll(); err != nil { 309 // t.Fatal(err) 310 // } 311 // enc := &json.ThriftEncoder{Proto: meta.ThriftBinary, Options: &json.Options{ 312 // WriteDefault: true, 313 // }} 314 // out, err := enc.Encode(simple, root) 315 // if err != nil { 316 // t.Fatal(err) 317 // } 318 // spew.Dump(out) 319 320 // stru := baseline.NewSimple() 321 // if _, err := stru.FastRead(out); err != nil { 322 // t.Fatal(err) 323 // } 324 // stru2 := baseline.NewSimple() 325 // if err := sonic.UnmarshalString(simpleJSON, stru2); err != nil { 326 // t.Fatal(err) 327 // } 328 // require.Equal(t, stru2, stru) 329 // } 330 331 func convertI642StringSimple(js string) string { 332 n, err := json.NewSearcher(js).GetByPath() 333 if err != nil { 334 panic(err) 335 } 336 old := n.Get("I64Field") 337 if old.Check() != nil { 338 panic(old) 339 } 340 new, err := old.Int64() 341 if err != nil { 342 panic(err) 343 } 344 _, err = n.Set("I64Field", json.NewString(strconv.Itoa(int(new)))) 345 if err != nil { 346 panic(err) 347 } 348 e, _ := n.Raw() 349 return e 350 } 351 352 func convertStr2I64Simple(js string) string { 353 n, err := json.NewSearcher(js).GetByPath() 354 if err != nil { 355 panic(err) 356 } 357 old := n.Get("I64Field") 358 if old.Check() != nil { 359 panic(old) 360 } 361 s, err := old.String() 362 if err != nil { 363 panic(err) 364 } 365 _, err = n.Set("I64Field", json.NewNumber(s[1:len(s)-1])) 366 if err != nil { 367 panic(err) 368 } 369 e, _ := n.Raw() 370 return e 371 } 372 373 func convertI642StringNesting(js string, itoa bool) string { 374 n, err := json.NewSearcher(js).GetByPath() 375 if err != nil { 376 panic(err) 377 } 378 c := n.Get("SimpleStruct") 379 r, _ := c.Raw() 380 var new string 381 if itoa { 382 new = convertI642StringSimple(r) 383 } else { 384 new = convertStr2I64Simple(r) 385 } 386 _, err = n.Set("SimpleStruct", json.NewRaw(new)) 387 if err != nil { 388 panic(err) 389 } 390 a := n.Get("ListSimple") 391 if a.Check() != nil { 392 panic(a) 393 } 394 a.ForEach(func(path json.Sequence, node *json.Node) bool { 395 r, _ := node.Raw() 396 var new string 397 if itoa { 398 new = convertI642StringSimple(r) 399 } else { 400 new = convertStr2I64Simple(r) 401 } 402 *node = json.NewRaw(new) 403 return true 404 }) 405 b := n.Get("MapStringSimple") 406 if b.Check() != nil { 407 panic(b) 408 } 409 b.ForEach(func(path json.Sequence, node *json.Node) bool { 410 r, _ := node.Raw() 411 var new string 412 if itoa { 413 new = convertI642StringSimple(r) 414 } else { 415 new = convertStr2I64Simple(r) 416 } 417 *node = json.NewRaw(new) 418 return true 419 }) 420 e, _ := n.Raw() 421 return e 422 } 423 424 func TestJSON2Thrift_Simple(t *testing.T) { 425 _, err := ejson.Marshal(baseline.Simple{}) 426 if err != nil { 427 t.Fatal(err) 428 } 429 simple := getSimpleDesc() 430 431 stru2 := baseline.NewSimple() 432 if err := sonic.UnmarshalString(simpleJSON, stru2); err != nil { 433 t.Fatal(err) 434 } 435 436 nj := convertI642StringSimple(simpleJSON) 437 cv := j2t.NewBinaryConv(conv.Options{ 438 WriteDefaultField: true, 439 EnableValueMapping: true, 440 }) 441 ctx := context.Background() 442 out, err := cv.Do(ctx, simple, []byte(nj)) 443 require.Nil(t, err) 444 445 stru := baseline.NewSimple() 446 if _, err := stru.FastRead(out); err != nil { 447 t.Fatal(err) 448 } 449 require.Equal(t, stru2, stru) 450 } 451 452 var Concurrency = 1000 453 454 func TestJSON2Thrift_Simple_Parallel(t *testing.T) { 455 _, err := ejson.Marshal(baseline.Simple{}) 456 if err != nil { 457 t.Fatal(err) 458 } 459 desc := getSimpleDesc() 460 stru2 := baseline.NewSimple() 461 if err := sonic.UnmarshalString(simpleJSON, stru2); err != nil { 462 t.Fatal(err) 463 } 464 nj := convertI642StringSimple(simpleJSON) 465 466 cv := j2t.NewBinaryConv(conv.Options{ 467 WriteDefaultField: true, 468 EnableValueMapping: true, 469 }) 470 471 wg := sync.WaitGroup{} 472 for i := 0; i < Concurrency; i++ { 473 wg.Add(1) 474 go func(i int) { 475 defer func() { 476 if r := recover(); r != nil { 477 t.Fatalf("panic: %d\n%s", i, nj) 478 } 479 }() 480 defer wg.Done() 481 ctx := context.Background() 482 out, err := cv.Do(ctx, desc, []byte(nj)) 483 require.Nil(t, err) 484 485 stru := baseline.NewSimple() 486 if _, err := stru.FastRead(out); err != nil { 487 t.Fatal(err) 488 } 489 require.Equal(t, stru2, stru) 490 }(i) 491 } 492 493 wg.Wait() 494 } 495 496 // func TestThriftEncodeNesting_Load(t *testing.T) { 497 // nesting := getNestingDesc() 498 // // fmt.Printf("%#v", nesting) 499 // root, err := json.NewSearcher(nestingJSON).GetByPath() 500 // if err != nil { 501 // t.Fatal(err) 502 // } 503 // if err := root.LoadAll(); err != nil { 504 // t.Fatal(err) 505 // } 506 // // js, err := root.MarshalJSON() 507 // // println(string(js)) 508 // enc := &json.ThriftEncoder{Proto: meta.ThriftBinary, Options: &json.Options{ 509 // WriteDefault: true, 510 // }} 511 // out, err := enc.Encode(nesting, root) 512 // if err != nil { 513 // t.Fatal(err) 514 // } 515 // // spew.Dump(out) 516 517 // stru := baseline.NewNesting() 518 // if _, err := stru.FastRead(out); err != nil { 519 // t.Fatal(err) 520 // } 521 // stru2 := baseline.NewNesting() 522 // if err := sonic.UnmarshalString(nestingJSON, stru2); err != nil { 523 // t.Fatal(err) 524 // } 525 // require.Equal(t, stru, stru2) 526 // // fmt.Printf("%#v", *stru) 527 // } 528 529 func TestHTTP2Thrift_Nesting(t *testing.T) { 530 nesting := getNestingDesc() 531 // fmt.Printf("%#v", nesting) 532 stru2 := baseline.NewNesting() 533 if err := ejson.Unmarshal([]byte(nestingJSON), stru2); err != nil { 534 t.Fatal(err) 535 } 536 537 req := getSampleHttpRequest(stru2, nestingJSON) 538 ctx := context.WithValue(context.Background(), conv.CtxKeyHTTPRequest, req) 539 cv := j2t.NewBinaryConv(conv.Options{ 540 WriteDefaultField: true, 541 EnableHttpMapping: true, 542 EnableValueMapping: true, 543 TracebackRequredOrRootFields: true, 544 ReadHttpValueFallback: true, 545 }) 546 nj := convertI642StringNesting(nestingJSON, true) 547 out, err := cv.Do(ctx, nesting, []byte(nj)) 548 require.Nil(t, err) 549 550 stru := baseline.NewNesting() 551 if _, err := stru.FastRead(out); err != nil { 552 t.Fatal(err) 553 } 554 555 require.Equal(t, stru2, stru) 556 // fmt.Printf("%#v", *stru) 557 } 558 559 func TestHTTP2Thrift_Nesting_Parallel(t *testing.T) { 560 nesting := getNestingDesc() 561 // fmt.Printf("%#v", nesting) 562 563 cv := j2t.NewBinaryConv(conv.Options{ 564 WriteDefaultField: true, 565 EnableHttpMapping: true, 566 EnableValueMapping: true, 567 TracebackRequredOrRootFields: true, 568 ReadHttpValueFallback: true, 569 OmitHttpMappingErrors: true, 570 }) 571 nj := convertI642StringNesting(nestingJSON, true) 572 println(nj) 573 574 wg := sync.WaitGroup{} 575 for i := 0; i < Concurrency; i++ { 576 wg.Add(1) 577 go func(i int) { 578 defer func() { 579 if r := recover(); r != nil { 580 t.Fatalf("panic: %d\n", i) 581 } 582 }() 583 defer wg.Done() 584 stru2 := baseline.NewNesting() 585 if err := ejson.Unmarshal([]byte(nestingJSON), stru2); err != nil { 586 t.Fatal(err) 587 } 588 req := getSampleHttpRequest(stru2, nestingJSON) 589 ctx := context.WithValue(context.Background(), conv.CtxKeyHTTPRequest, req) 590 out, err := cv.Do(ctx, nesting, []byte(nj)) 591 require.Nil(t, err) 592 stru := baseline.NewNesting() 593 if _, err := stru.FastRead(out); err != nil { 594 t.Fatal(err) 595 } 596 require.Equal(t, stru2, stru) 597 }(i) 598 } 599 wg.Wait() 600 } 601 602 // func BenchmarkJSON2Thrift_DynamicGo_Load(b *testing.B) { 603 // b.Run("small", func(b *testing.B) { 604 // simple := getSimpleDesc() 605 // enc := &json.ThriftEncoder{Proto: meta.ThriftBinary, Options: &json.Options{ 606 // WriteDefault: true, 607 // }} 608 // jSimple, _ := json.NewSearcher(simpleJSON).GetByPath() 609 // jSimple.LoadAll() 610 // out, err := enc.Encode(simple, jSimple) 611 // if err != nil { 612 // b.Fatal(err) 613 // } 614 // b.SetBytes(int64(len(out))) 615 // b.ResetTimer() 616 // for i := 0; i < b.N; i++ { 617 // jSimple := json.NewRaw(simpleJSON) 618 // jSimple.LoadAll() 619 // _, _ = enc.Encode(simple, jSimple) 620 // } 621 // }) 622 623 // b.Run("medium", func(b *testing.B) { 624 // nesting := getNestingDesc() 625 // enc := &json.ThriftEncoder{Proto: meta.ThriftBinary, Options: &json.Options{ 626 // WriteDefault: true, 627 // }} 628 // jNesting, _ := json.NewSearcher(nestingJSON).GetByPath() 629 // jNesting.LoadAll() 630 // out, err := enc.Encode(nesting, jNesting) 631 // if err != nil { 632 // b.Fatal(err) 633 // } 634 // b.SetBytes(int64(len(out))) 635 // b.ResetTimer() 636 // for i := 0; i < b.N; i++ { 637 // jNesting := json.NewRaw(nestingJSON) 638 // jNesting.LoadAll() 639 // _, _ = enc.Encode(nesting, jNesting) 640 // } 641 // }) 642 // } 643 644 // func BenchmarkJSON2Thrift_DynamicGo_Raw(b *testing.B) { 645 646 // b.Run("small", func(b *testing.B) { 647 // simple := getSimpleDesc() 648 // enc := &json.ThriftEncoder{Proto: meta.ThriftBinary, Options: &json.Options{ 649 // WriteDefault: true, 650 // }} 651 // jSimple := json.NewRaw(simpleJSON) 652 // out, err := enc.Encode(simple, jSimple) 653 // if err != nil { 654 // b.Fatal(err) 655 // } 656 // b.SetBytes(int64(len(out))) 657 // b.ResetTimer() 658 // for i := 0; i < b.N; i++ { 659 // jSimple := json.NewRaw(simpleJSON) 660 // _, _ = enc.Encode(simple, jSimple) 661 // } 662 // }) 663 664 // b.Run("medium", func(b *testing.B) { 665 // nesting := getNestingDesc() 666 // enc := &json.ThriftEncoder{Proto: meta.ThriftBinary, Options: &json.Options{ 667 // WriteDefault: true, 668 // }} 669 // jNesting, _ := json.NewSearcher(nestingJSON).GetByPath() 670 // out, err := enc.Encode(nesting, jNesting) 671 // if err != nil { 672 // b.Fatal(err) 673 // } 674 // b.SetBytes(int64(len(out))) 675 // b.ResetTimer() 676 // for i := 0; i < b.N; i++ { 677 // jNesting := json.NewRaw(nestingJSON) 678 // _, _ = enc.Encode(nesting, jNesting) 679 // } 680 // }) 681 // } 682 683 const BufferSize = 4096 684 685 func BenchmarkJSON2Thrift_KitexGeneric(b *testing.B) { 686 p, err := generic.NewThriftFileProvider(idlPath) 687 if err != nil { 688 b.Fatal(err) 689 } 690 svcDsc := <-p.Provide() 691 692 b.Run("small", func(b *testing.B) { 693 var _args generic.Args 694 _args.Method = "SimpleMethod" 695 _args.Request = simpleJSON 696 codec, err := gthrift.NewWriteJSON(svcDsc, "SimpleMethod", true) 697 if err != nil { 698 b.Fatal(err) 699 } 700 var mm = athrift.NewTMemoryBuffer() 701 bc := athrift.NewTBinaryProtocol(mm, false, true) 702 if err := codec.Write(context.Background(), bc, simpleJSON, nil); err != nil { 703 b.Fatal(err) 704 } 705 706 b.SetBytes(int64(len(mm.Bytes()))) 707 b.ResetTimer() 708 for i := 0; i < b.N; i++ { 709 mm.Reset() 710 _ = codec.Write(context.Background(), bc, simpleJSON, nil) 711 } 712 }) 713 714 b.Run("medium", func(b *testing.B) { 715 var _args generic.Args 716 _args.Method = "NestingMethod" 717 _args.Request = nestingJSON 718 codec, err := gthrift.NewWriteJSON(svcDsc, "NestingMethod", true) 719 if err != nil { 720 b.Fatal(err) 721 } 722 var mm = athrift.NewTMemoryBuffer() 723 bc := athrift.NewTBinaryProtocol(mm, false, true) 724 if err := codec.Write(context.Background(), bc, nestingJSON, nil); err != nil { 725 b.Fatal(err) 726 } 727 728 b.SetBytes(int64(len(mm.Bytes()))) 729 b.ResetTimer() 730 for i := 0; i < b.N; i++ { 731 mm.Reset() 732 _ = codec.Write(context.Background(), bc, nestingJSON, nil) 733 } 734 }) 735 } 736 737 func BenchmarkJSON2Thrift_SonicAndKitex(b *testing.B) { 738 b.Run("small", func(b *testing.B) { 739 v := baseline.NewSimple() 740 if err := sonic.UnmarshalString(simpleJSON, v); err != nil { 741 b.Fatal(err) 742 } 743 var buf = make([]byte, v.BLength()) 744 if err := v.FastWriteNocopy(buf, nil); err <= 0 { 745 b.Fatal(err) 746 } 747 748 b.SetBytes(int64(len(buf))) 749 b.ResetTimer() 750 for i := 0; i < b.N; i++ { 751 v := baseline.NewSimple() 752 _ = v.BLength() 753 _ = sonic.UnmarshalString(simpleJSON, v) 754 v.FastWriteNocopy(buf, nil) 755 } 756 }) 757 758 b.Run("medium", func(b *testing.B) { 759 v := baseline.NewNesting() 760 if err := sonic.UnmarshalString(nestingJSON, v); err != nil { 761 b.Fatal(err) 762 } 763 var buf = make([]byte, v.BLength()) 764 if err := v.FastWriteNocopy(buf, nil); err <= 0 { 765 b.Fatal(err) 766 } 767 768 b.SetBytes(int64(len(buf))) 769 b.ResetTimer() 770 for i := 0; i < b.N; i++ { 771 v := baseline.NewNesting() 772 _ = v.BLength() 773 _ = sonic.UnmarshalString(nestingJSON, v) 774 v.FastWriteNocopy(buf, nil) 775 } 776 }) 777 } 778 779 func BenchmarkHTTP2Thrift_DynamicGo_Raw(b *testing.B) { 780 b.Run("small/value_mapping", func(b *testing.B) { 781 simple := getSimpleDesc() 782 cv := j2t.NewBinaryConv(conv.Options{ 783 WriteDefaultField: true, 784 EnableValueMapping: true, 785 }) 786 nj := []byte(convertI642StringSimple(simpleJSON)) 787 ctx := context.Background() 788 out, err := cv.Do(ctx, simple, nj) 789 require.Nil(b, err) 790 791 b.SetBytes(int64(len(out))) 792 b.ResetTimer() 793 for i := 0; i < b.N; i++ { 794 _, _ = cv.Do(ctx, simple, nj) 795 } 796 }) 797 798 b.Run("medium/value_mapping", func(b *testing.B) { 799 nesting := getNestingDesc() 800 req := getSampleHttpRequest(baseline.NewNesting(), nestingJSON) 801 cv := j2t.NewBinaryConv(conv.Options{ 802 WriteDefaultField: true, 803 EnableValueMapping: true, 804 }) 805 nj := []byte(convertI642StringNesting(nestingJSON, true)) 806 ctx := context.Background() 807 ctx = context.WithValue(ctx, conv.CtxKeyHTTPRequest, req) 808 out, err := cv.Do(ctx, nesting, nj) 809 require.Nil(b, err) 810 811 b.SetBytes(int64(len(out))) 812 b.ResetTimer() 813 for i := 0; i < b.N; i++ { 814 _, _ = cv.Do(ctx, nesting, nj) 815 } 816 }) 817 818 b.Run("medium/http+value_mapping", func(b *testing.B) { 819 nesting := getNestingDesc() 820 req := getSampleHttpRequest(baseline.NewNesting(), nestingJSON) 821 ctx := context.Background() 822 ctx = context.WithValue(ctx, conv.CtxKeyHTTPRequest, req) 823 cv := j2t.NewBinaryConv(conv.Options{ 824 WriteDefaultField: true, 825 EnableHttpMapping: true, 826 EnableValueMapping: true, 827 }) 828 nj := []byte(convertI642StringNesting(nestingJSON, true)) 829 out, err := cv.Do(ctx, nesting, nj) 830 require.Nil(b, err) 831 832 b.SetBytes(int64(len(out))) 833 b.ResetTimer() 834 for i := 0; i < b.N; i++ { 835 _, _ = cv.Do(ctx, nesting, nj) 836 } 837 }) 838 } 839 840 // func getKitexHttpRequest(req *descriptor.HTTPRequest) { 841 // header := "你好" 842 // req.Header.Set("String", header) 843 // // exp.String_ = header 844 // // h2 := "abcdefghijklmnopqrstuvwxyz" 845 // // req.Header.Set("string_field", h2) 846 // // exp.SimpleStruct.StringField = h2 847 // // for i := range exp.ListSimple { 848 // // exp.ListSimple[i].StringField = h2 849 // // } 850 // // for k := range exp.MapStringSimple { 851 // // exp.MapStringSimple[k].StringField = h2 852 // // } 853 854 // c := []int64{-1, 0, math.MaxInt64, math.MinInt64} 855 // cookie := "" 856 // for i, v := range c { 857 // cookie += strconv.Itoa(int(v)) 858 // if i != len(c)-1 { 859 // cookie += "," 860 // } 861 // } 862 // req.Cookies["list_i64"] = cookie 863 // // exp.ListI64 = c 864 865 // // param := math.MaxFloat64 866 // // req.Params.Set("double", strconv.FormatFloat(param, 'f', -1, 64)) 867 // // exp.Double = param 868 869 // q := []int32{-1, 0, math.MaxInt32, math.MinInt32} 870 // query := "" 871 // for i, v := range q { 872 // query += strconv.Itoa(int(v)) 873 // if i != len(q)-1 { 874 // query += "," 875 // } 876 // } 877 // req.Query.Set("ListI32", query) 878 // // exp.ListI32 = q 879 880 // // exp.I32 = 0 881 882 // var helper = func(sim map[string]interface{}) { 883 // sim["I32Field"] = int32(sim["I32Field"].(int64)) 884 // sim["ByteField"] = int8(sim["ByteField"].(int64)) 885 // } 886 // for _, v := range req.Body["MapStringSimple"].(map[string]interface{}) { 887 // helper(v.(map[string]interface{})) 888 // } 889 // for _, v := range req.Body["ListSimple"].([]interface{}) { 890 // helper(v.(map[string]interface{})) 891 // } 892 // helper(req.Body["SimpleStruct"].(map[string]interface{})) 893 // req.Body["Byte"] = int8(req.Body["Byte"].(int64)) 894 895 // } 896 897 func BenchmarkHTTP2Thrift_KitexGeneric(b *testing.B) { 898 p, err := generic.NewThriftFileProvider(idlPath) 899 if err != nil { 900 b.Fatal(err) 901 } 902 svcDsc := <-p.Provide() 903 svcDsc.Functions["NestingMethod"].Request.Struct.FieldsByName["req"].Type.Struct.FieldsByName["Double"].HTTPMapping = nil 904 905 b.Run("small", func(b *testing.B) { 906 codec := gthrift.NewWriteHTTPRequest(svcDsc) 907 req := &descriptor.HTTPRequest{} 908 req.Request, err = stdh.NewRequest("POST", "/simple", nil) 909 if err != nil { 910 b.Fatal(err) 911 } 912 jc := sonic.Config{ 913 UseInt64: true, 914 }.Froze() 915 if err := jc.UnmarshalFromString(simpleJSON, &req.Body); err != nil { 916 b.Fatal(err) 917 } 918 req.Body["I32Field"] = int32(req.Body["I32Field"].(int64)) 919 req.Body["ByteField"] = int8(req.Body["ByteField"].(int64)) 920 921 buf := remote.NewWriterBuffer(BufferSize) 922 bc := bthrift.NewBinaryProtocol(buf) 923 if err := codec.Write(context.Background(), bc, req, gthrift.NewBase()); err != nil { 924 b.Fatal(err) 925 } 926 out, _ := buf.Bytes() 927 exp := baseline.NewSimple() 928 if _, err := exp.FastRead(out); err != nil { 929 b.Fatal(err) 930 } 931 932 b.SetBytes(int64(len(out))) 933 b.ResetTimer() 934 for i := 0; i < b.N; i++ { 935 buf := remote.NewWriterBuffer(BufferSize) 936 bc := bthrift.NewBinaryProtocol(buf) 937 if err = codec.Write(context.Background(), bc, req, gthrift.NewBase()); err != nil { 938 b.Fatal(err) 939 } 940 } 941 }) 942 943 // b.Run("medium", func(b *testing.B) { 944 // codec := gthrift.NewWriteHTTPRequest(svcDsc) 945 // jc := sonic.Config{ 946 // UseInt64: true, 947 // }.Froze() 948 // var body map[string]interface{} 949 // if err := jc.UnmarshalFromString(nestingJSON, &body); err != nil { 950 // b.Fatal(err) 951 // } 952 // req := &descriptor.HTTPRequest{ 953 // Header: map[string][]string{}, 954 // Query: map[string][]string{}, 955 // Cookies: map[string]string{}, 956 // } 957 // req.Body = body 958 // getKitexHttpRequest(req) 959 // req.Method = "POST" 960 // req.Path = "/nesting" 961 962 // buf := remote.NewWriterBuffer(BufferSize) 963 // bc := bthrift.NewBinaryProtocol(buf) 964 // if err := codec.Write(context.Background(), bc, req, gthrift.NewBase()); err != nil { 965 // b.Fatal(err) 966 // } 967 // out, _ := buf.Bytes() 968 // exp := baseline.NewNesting() 969 // if _, err := exp.FastRead(out); err != nil { 970 // b.Fatal(err) 971 // } 972 973 // b.SetBytes(int64(len(out))) 974 // b.ResetTimer() 975 // for i := 0; i < b.N; i++ { 976 // buf := remote.NewWriterBuffer(BufferSize) 977 // bc := bthrift.NewBinaryProtocol(buf) 978 // if err = codec.Write(context.Background(), bc, req, gthrift.NewBase()); err != nil { 979 // b.Fatal(err) 980 // } 981 // } 982 // }) 983 }