From ca414d707a6b10c41b65ed9bee127773f2bcf0fc Mon Sep 17 00:00:00 2001 From: John Howard Date: Wed, 21 Sep 2022 11:54:37 -0700 Subject: [PATCH 1/2] Optimize `Everything` and `Nothing` label selectors Currently each call makes 1 small alloc. This is not much, but it adds up when this is called millions of times. This simple change just moves to using a shared struct between everything. This is safe as each operation on the Selector is not doing mutations. --- staging/src/k8s.io/apimachinery/pkg/labels/selector.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/staging/src/k8s.io/apimachinery/pkg/labels/selector.go b/staging/src/k8s.io/apimachinery/pkg/labels/selector.go index 6d6f562ad13..06b0aa53738 100644 --- a/staging/src/k8s.io/apimachinery/pkg/labels/selector.go +++ b/staging/src/k8s.io/apimachinery/pkg/labels/selector.go @@ -74,9 +74,11 @@ type Selector interface { RequiresExactMatch(label string) (value string, found bool) } +var everythingSelector Selector = internalSelector{} + // Everything returns a selector that matches all labels. func Everything() Selector { - return internalSelector{} + return everythingSelector } type nothingSelector struct{} @@ -91,9 +93,11 @@ func (n nothingSelector) RequiresExactMatch(label string) (value string, found b return "", false } +var internalNothingSelector Selector = nothingSelector{} + // Nothing returns a selector that matches no labels func Nothing() Selector { - return nothingSelector{} + return internalNothingSelector } // NewSelector returns a nil selector From 916fe2f89610a058603c1aa5260cd45841aadb0c Mon Sep 17 00:00:00 2001 From: John Howard Date: Tue, 1 Nov 2022 13:36:26 -0700 Subject: [PATCH 2/2] Rename and comment on why sharing is safe --- staging/src/k8s.io/apimachinery/pkg/labels/selector.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/staging/src/k8s.io/apimachinery/pkg/labels/selector.go b/staging/src/k8s.io/apimachinery/pkg/labels/selector.go index 06b0aa53738..8910043890c 100644 --- a/staging/src/k8s.io/apimachinery/pkg/labels/selector.go +++ b/staging/src/k8s.io/apimachinery/pkg/labels/selector.go @@ -74,11 +74,12 @@ type Selector interface { RequiresExactMatch(label string) (value string, found bool) } -var everythingSelector Selector = internalSelector{} +// Sharing this saves 1 alloc per use; this is safe because it's immutable. +var sharedEverythingSelector Selector = internalSelector{} // Everything returns a selector that matches all labels. func Everything() Selector { - return everythingSelector + return sharedEverythingSelector } type nothingSelector struct{} @@ -93,11 +94,12 @@ func (n nothingSelector) RequiresExactMatch(label string) (value string, found b return "", false } -var internalNothingSelector Selector = nothingSelector{} +// Sharing this saves 1 alloc per use; this is safe because it's immutable. +var sharedNothingSelector Selector = nothingSelector{} // Nothing returns a selector that matches no labels func Nothing() Selector { - return internalNothingSelector + return sharedNothingSelector } // NewSelector returns a nil selector