mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 11:21:47 +00:00
Improved FormatMap: Improves performance by about 4x, or nearly 2x in the worst case (#112661)
* Improved FormatMap Improves performance by about 4x, or nearly 2x in the worst case old FormatMap BenchmarkFormatMap-12 873046 1238 ns/op 384 B/op 13 allocs/op new FormatMap BenchmarkFormatMap-12 3665762 327.0 ns/op 152 B/op 3 allocs/op Signed-off-by: aimuz <mr.imuz@gmail.com> * fixed Signed-off-by: aimuz <mr.imuz@gmail.com> * fixed Signed-off-by: aimuz <mr.imuz@gmail.com> * test: fix test Signed-off-by: aimuz <mr.imuz@gmail.com> --------- Signed-off-by: aimuz <mr.imuz@gmail.com>
This commit is contained in:
parent
d788d436c9
commit
571adf6e84
@ -18,26 +18,36 @@ package fieldpath
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
|
||||||
"k8s.io/apimachinery/pkg/util/validation"
|
"k8s.io/apimachinery/pkg/util/validation"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FormatMap formats map[string]string to a string.
|
// FormatMap formats map[string]string to a string.
|
||||||
func FormatMap(m map[string]string) (fmtStr string) {
|
func FormatMap(m map[string]string) (fmtStr string) {
|
||||||
// output with keys in sorted order to provide stable output
|
// output with keys in sorted order to provide stable output
|
||||||
keys := sets.NewString()
|
keys := make([]string, 0, len(m))
|
||||||
for key := range m {
|
var grow int
|
||||||
keys.Insert(key)
|
for k, v := range m {
|
||||||
|
keys = append(keys, k)
|
||||||
|
// why add 4: (for =, \n, " and ")
|
||||||
|
grow += len(k) + len(v) + 4
|
||||||
}
|
}
|
||||||
for _, key := range keys.List() {
|
sort.Strings(keys)
|
||||||
fmtStr += fmt.Sprintf("%v=%q\n", key, m[key])
|
// allocate space to avoid expansion
|
||||||
|
dst := make([]byte, 0, grow)
|
||||||
|
for _, key := range keys {
|
||||||
|
if len(dst) > 0 {
|
||||||
|
dst = append(dst, '\n')
|
||||||
|
}
|
||||||
|
dst = append(dst, key...)
|
||||||
|
dst = append(dst, '=')
|
||||||
|
dst = strconv.AppendQuote(dst, m[key])
|
||||||
}
|
}
|
||||||
fmtStr = strings.TrimSuffix(fmtStr, "\n")
|
return string(dst)
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractFieldPathAsString extracts the field from the given object
|
// ExtractFieldPathAsString extracts the field from the given object
|
||||||
|
@ -24,6 +24,30 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func BenchmarkFormatMap(b *testing.B) {
|
||||||
|
var s string
|
||||||
|
m := map[string]string{
|
||||||
|
"spec.pod.beta.kubernetes.io/statefulset-index": "1",
|
||||||
|
"Www.k8s.io/test": "1",
|
||||||
|
"foo": "bar",
|
||||||
|
"flannel.alpha.coreos.com/backend-data": `{"VNI":1,"VtepMAC":"ce:f9:c7:a4:de:64"}`,
|
||||||
|
"flannel.alpha.coreos.com/backend-type": "vxlan",
|
||||||
|
"flannel.alpha.coreos.com/kube-subnet-manager": "true",
|
||||||
|
"flannel.alpha.coreos.com/public-ip": "192.168.19.160",
|
||||||
|
"management.cattle.io/pod-limits": `{"cpu":"11400m","memory":"7965Mi"}`,
|
||||||
|
"management.cattle.io/pod-requests": `{"cpu":"2482m","memory":"7984Mi","pods":"26"}`,
|
||||||
|
"node.alpha.kubernetes.io/ttl": "0",
|
||||||
|
"volumes.kubernetes.io/controller-managed-attach-detach": "true",
|
||||||
|
}
|
||||||
|
b.ReportAllocs()
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
s = FormatMap(m)
|
||||||
|
}
|
||||||
|
// Avoid compiler optimizations
|
||||||
|
_ = s
|
||||||
|
}
|
||||||
|
|
||||||
func TestExtractFieldPathAsString(t *testing.T) {
|
func TestExtractFieldPathAsString(t *testing.T) {
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
name string
|
name string
|
||||||
@ -268,3 +292,72 @@ func TestSplitMaybeSubscriptedPath(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestFormatMap
|
||||||
|
func TestFormatMap(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
m map[string]string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
wantFmtStr string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "nil",
|
||||||
|
args: args{
|
||||||
|
m: nil,
|
||||||
|
},
|
||||||
|
wantFmtStr: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "label",
|
||||||
|
args: args{
|
||||||
|
m: map[string]string{
|
||||||
|
"beta.kubernetes.io/os": "linux",
|
||||||
|
"kubernetes.io/arch": "amd64",
|
||||||
|
"kubernetes.io/hostname": "master01",
|
||||||
|
"kubernetes.io/os": "linux",
|
||||||
|
"node-role.kubernetes.io/control-plane": "true",
|
||||||
|
"node-role.kubernetes.io/master": "true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantFmtStr: `beta.kubernetes.io/os="linux"
|
||||||
|
kubernetes.io/arch="amd64"
|
||||||
|
kubernetes.io/hostname="master01"
|
||||||
|
kubernetes.io/os="linux"
|
||||||
|
node-role.kubernetes.io/control-plane="true"
|
||||||
|
node-role.kubernetes.io/master="true"`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "annotation",
|
||||||
|
args: args{
|
||||||
|
m: map[string]string{
|
||||||
|
"flannel.alpha.coreos.com/backend-data": `{"VNI":1,"VtepMAC":"ce:f9:c7:a4:de:64"}`,
|
||||||
|
"flannel.alpha.coreos.com/backend-type": "vxlan",
|
||||||
|
"flannel.alpha.coreos.com/kube-subnet-manager": "true",
|
||||||
|
"flannel.alpha.coreos.com/public-ip": "192.168.19.160",
|
||||||
|
"management.cattle.io/pod-limits": `{"cpu":"11400m","memory":"7965Mi"}`,
|
||||||
|
"management.cattle.io/pod-requests": `{"cpu":"2482m","memory":"7984Mi","pods":"26"}`,
|
||||||
|
"node.alpha.kubernetes.io/ttl": "0",
|
||||||
|
"volumes.kubernetes.io/controller-managed-attach-detach": "true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantFmtStr: `flannel.alpha.coreos.com/backend-data="{\"VNI\":1,\"VtepMAC\":\"ce:f9:c7:a4:de:64\"}"
|
||||||
|
flannel.alpha.coreos.com/backend-type="vxlan"
|
||||||
|
flannel.alpha.coreos.com/kube-subnet-manager="true"
|
||||||
|
flannel.alpha.coreos.com/public-ip="192.168.19.160"
|
||||||
|
management.cattle.io/pod-limits="{\"cpu\":\"11400m\",\"memory\":\"7965Mi\"}"
|
||||||
|
management.cattle.io/pod-requests="{\"cpu\":\"2482m\",\"memory\":\"7984Mi\",\"pods\":\"26\"}"
|
||||||
|
node.alpha.kubernetes.io/ttl="0"
|
||||||
|
volumes.kubernetes.io/controller-managed-attach-detach="true"`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if gotFmtStr := FormatMap(tt.args.m); gotFmtStr != tt.wantFmtStr {
|
||||||
|
t.Errorf("FormatMap() = %v, want %v", gotFmtStr, tt.wantFmtStr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user