integrate request builder into HTTP client for googleapis support (#157)
This commit is contained in:
149
builder/request_builder_bench_test.go
Normal file
149
builder/request_builder_bench_test.go
Normal file
@@ -0,0 +1,149 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
pb "go.unistack.org/micro-client-http/v4/builder/proto"
|
||||
)
|
||||
|
||||
// sink prevents the compiler from optimizing away parsePathTemplate results.
|
||||
var sink *pathTemplate
|
||||
|
||||
func BenchmarkParsePathTemplate(b *testing.B) {
|
||||
r := rand.New(rand.NewSource(1))
|
||||
|
||||
benchInput := func(size int) string {
|
||||
sb := strings.Builder{}
|
||||
sb.Grow(size * 10)
|
||||
|
||||
for i := 0; i < size; i++ {
|
||||
name := fmt.Sprintf("var%d", r.Intn(1000))
|
||||
|
||||
if r.Intn(5) == 0 {
|
||||
sb.WriteString(fmt.Sprintf("{%s=**}", name))
|
||||
} else {
|
||||
sb.WriteString(fmt.Sprintf("{%s}", name))
|
||||
}
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
sizes := []int{1_000, 10_000, 50_000, 100_000}
|
||||
for _, size := range sizes {
|
||||
input := benchInput(size)
|
||||
b.Run(fmt.Sprintf("N=%d", size), func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
var err error
|
||||
sink, err = parsePathTemplate(input)
|
||||
if err != nil && testing.Verbose() {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkRequestBuilder(b *testing.B) {
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
|
||||
makeMsg := func(fieldCount int) proto.Message {
|
||||
switch fieldCount {
|
||||
case 5:
|
||||
return &pb.Benchmark_Case5{
|
||||
Field1: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field2: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field3: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field4: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field5: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
}
|
||||
case 10:
|
||||
return &pb.Benchmark_Case10{
|
||||
Field1: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field2: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field3: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field4: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field5: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field6: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field7: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field8: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field9: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field10: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
}
|
||||
case 30:
|
||||
return &pb.Benchmark_Case30{
|
||||
Field1: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field2: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field3: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field4: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field5: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field6: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field7: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field8: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field9: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field10: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field11: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field12: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field13: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field14: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field15: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field16: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field17: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field18: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field19: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field20: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field21: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field22: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field23: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field24: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field25: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field26: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field27: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field28: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field29: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
Field30: fmt.Sprintf("value%d", r.Intn(1000)),
|
||||
}
|
||||
default:
|
||||
b.Fatal("undefined field count")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
pathTmpl string
|
||||
bodyOption string
|
||||
}{
|
||||
{"all fields in path", "/resource/{field1}/{field2}", ""},
|
||||
{"single field body", "/resource/{field1}", "field4"},
|
||||
{"full body", "/resource", "*"},
|
||||
}
|
||||
|
||||
for _, fields := range []int{5, 10, 30} {
|
||||
for _, tt := range tests {
|
||||
b.Run(fmt.Sprintf("%s_%d_fields", tt.name, fields), func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
msg := makeMsg(fields)
|
||||
rb, err := NewRequestBuilder(tt.pathTmpl, "POST", tt.bodyOption, msg)
|
||||
if err != nil {
|
||||
b.Fatalf("new request builder: %v", err)
|
||||
}
|
||||
|
||||
_, _, err = rb.Build()
|
||||
if err != nil {
|
||||
b.Fatalf("build: %v", err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user