From c076bfc4951566a2706a0c1d7e8ac9150216d5cb Mon Sep 17 00:00:00 2001 From: wojtekt Date: Thu, 3 Oct 2019 17:17:58 +0200 Subject: [PATCH] Avoid unnecessary identifier computations --- .../serializer/versioning/versioning.go | 22 +++++++++++++++---- .../serializer/versioning/versioning_test.go | 13 +++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go b/staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go index b0ea728fa71..ced184c91e5 100644 --- a/staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go +++ b/staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go @@ -20,6 +20,7 @@ import ( "encoding/json" "io" "reflect" + "sync" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -88,21 +89,34 @@ type codec struct { originalSchemeName string } +var identifiersMap sync.Map + +type codecIdentifier struct { + EncodeGV string `json:"encodeGV,omitempty"` + Encoder string `json:"encoder,omitempty"` + Name string `json:"name,omitempty"` +} + // identifier computes Identifier of Encoder based on codec parameters. func identifier(encodeGV runtime.GroupVersioner, encoder runtime.Encoder) runtime.Identifier { - result := map[string]string{ - "name": "versioning", + result := codecIdentifier{ + Name: "versioning", } + if encodeGV != nil { - result["encodeGV"] = encodeGV.Identifier() + result.EncodeGV = encodeGV.Identifier() } if encoder != nil { - result["encoder"] = string(encoder.Identifier()) + result.Encoder = string(encoder.Identifier()) + } + if id, ok := identifiersMap.Load(result); ok { + return id.(runtime.Identifier) } identifier, err := json.Marshal(result) if err != nil { klog.Fatalf("Failed marshaling identifier for codec: %v", err) } + identifiersMap.Store(result, runtime.Identifier(identifier)) return runtime.Identifier(identifier) } diff --git a/staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning_test.go b/staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning_test.go index 0522a6827ef..14d598ff5b7 100644 --- a/staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning_test.go +++ b/staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning_test.go @@ -381,3 +381,16 @@ func TestCacheableObject(t *testing.T) { runtimetesting.CacheableObjectTest(t, encoder) } + +func BenchmarkIdentifier(b *testing.B) { + encoder := &mockSerializer{} + gv := schema.GroupVersion{Group: "group", Version: "version"} + + for i := 0; i < b.N; i++ { + id := identifier(gv, encoder) + // Avoid optimizing by compiler. + if id[0] != '{' { + b.Errorf("unexpected identifier: %s", id) + } + } +}