diff --git a/aws/protocol/query/object.go b/aws/protocol/query/object.go index 455b92515ca..261a2724f73 100644 --- a/aws/protocol/query/object.go +++ b/aws/protocol/query/object.go @@ -1,9 +1,6 @@ package query -import ( - "fmt" - "net/url" -) +import "net/url" // Object represents the encoding of Query structures and unions. A Query // object is a representation of a mapping of string keys to arbitrary @@ -56,14 +53,14 @@ func (o *Object) FlatKey(name string) Value { func (o *Object) key(name string, flatValue bool) Value { if o.prefix != "" { - return newValue(o.values, fmt.Sprintf("%s.%s", o.prefix, name), flatValue) + return newValue(o.values, o.prefix+keySeparator+name, flatValue) } return newValue(o.values, name, flatValue) } func (o *Object) keyWithValues(name string, flatValue bool) Value { if o.prefix != "" { - return newAppendValue(o.values, fmt.Sprintf("%s.%s", o.prefix, name), flatValue) + return newAppendValue(o.values, o.prefix+keySeparator+name, flatValue) } return newAppendValue(o.values, name, flatValue) } diff --git a/aws/protocol/query/value.go b/aws/protocol/query/value.go index a9251521f12..8063c592ddd 100644 --- a/aws/protocol/query/value.go +++ b/aws/protocol/query/value.go @@ -7,6 +7,8 @@ import ( "github.com/aws/smithy-go/encoding/httpbinding" ) +const keySeparator = "." + // Value represents a Query Value type. type Value struct { // The query values to add the value to. diff --git a/aws/protocol/query/value_test.go b/aws/protocol/query/value_test.go new file mode 100644 index 00000000000..f8336f39d46 --- /dev/null +++ b/aws/protocol/query/value_test.go @@ -0,0 +1,64 @@ +package query + +import ( + "fmt" + "strconv" + "testing" +) + +var output string + +func Benchmark_sprintf_strings(b *testing.B) { + for i := 0; i < b.N; i++ { + output = fmt.Sprintf("%s.%s", "foo", "bar") + } +} + +func Benchmark_concat_strings(b *testing.B) { + for i := 0; i < b.N; i++ { + output = "foo" + keySeparator + "bar" + } +} + +func Benchmark_int_formatting(b *testing.B) { + benchmarkFuncs := []struct { + name string + formatter func(val int32) + }{ + { + name: "array - sprintf", formatter: func(val int32) { + output = fmt.Sprintf("%s.%d", "foo", val) + }, + }, + { + name: "array - concat strconv", formatter: func(val int32) { + output = "foo" + keySeparator + strconv.FormatInt(int64(val), 10) + }, + }, + { + name: "map - sprintf", formatter: func(val int32) { + output = fmt.Sprintf("%s.%d.%s", "foo", val, "bar") + output = fmt.Sprintf("%s.%d.%s", "foo", val, "bar") + }, + }, + { + name: "map - concat strconv", formatter: func(val int32) { + valString := strconv.FormatInt(int64(val), 10) + output = "foo" + keySeparator + valString + keySeparator + "bar" + output = "foo" + keySeparator + valString + keySeparator + "bar" + }, + }, + } + + sizesToTest := []int32{1, 10, 100, 250, 500, 1000} + + for _, bm := range benchmarkFuncs { + for _, size := range sizesToTest { + b.Run(fmt.Sprintf("%s with %d size", bm.name, size), func(b *testing.B) { + for i := 0; i < b.N; i++ { + bm.formatter(size) + } + }) + } + } +}