From a7c0467e011e13432571e6cee1340739b183449d Mon Sep 17 00:00:00 2001 From: Antoine Pelisse Date: Mon, 30 Jan 2023 09:46:23 -0800 Subject: [PATCH] apiextensions: Benchmark escaping in SchemaHas SchemaHas needs to escape the apiextensions.JSONSchemaProps pointer since it's calling an arbitrary predicate function that can keep a copy of the pointer (even though it shouldn't, but the compiler can't know that). The leak is resulting in a fair amount of memory allocation when installing many CRDs in a row (about 3% of the memory allocated happens in this method). --- .../validation/validation_test.go | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation_test.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation_test.go index 853110c2d6d..687d238b455 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation_test.go @@ -8624,6 +8624,30 @@ func TestSchemaHasDefaults(t *testing.T) { } } +func BenchmarkSchemaHas(b *testing.B) { + scheme := runtime.NewScheme() + codecs := serializer.NewCodecFactory(scheme) + if err := apiextensions.AddToScheme(scheme); err != nil { + b.Fatal(err) + } + fuzzerFuncs := fuzzer.MergeFuzzerFuncs(apiextensionsfuzzer.Funcs) + seed := int64(5577006791947779410) + f := fuzzer.FuzzerFor(fuzzerFuncs, rand.NewSource(seed), codecs) + // fuzz internal types + schema := &apiextensions.JSONSchemaProps{} + f.NilChance(0).NumElements(10, 10).MaxDepth(10).Fuzz(schema) + + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + if SchemaHas(schema, func(_ *apiextensions.JSONSchemaProps) bool { + return false + }) { + b.Errorf("Function returned true") + } + } +} + var example = apiextensions.JSON(`"This is an example"`) var validValidationSchema = &apiextensions.JSONSchemaProps{