From 407caf905da128681283d37bdfb6ef5a8dfcdc45 Mon Sep 17 00:00:00 2001 From: slinkydeveloper Date: Thu, 12 Nov 2020 14:58:42 +0100 Subject: [PATCH 1/6] Microbenchmark for attributes filter Signed-off-by: Francesco Guardiani --- .../benchmarks/attributes_benchmark_test.go | 40 +++++++++++++++++++ .../benchmarks/common_benchmark_test.go | 29 ++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 pkg/eventfilter/benchmarks/attributes_benchmark_test.go create mode 100644 pkg/eventfilter/benchmarks/common_benchmark_test.go diff --git a/pkg/eventfilter/benchmarks/attributes_benchmark_test.go b/pkg/eventfilter/benchmarks/attributes_benchmark_test.go new file mode 100644 index 00000000000..2c70a7dbfb7 --- /dev/null +++ b/pkg/eventfilter/benchmarks/attributes_benchmark_test.go @@ -0,0 +1,40 @@ +package benchmarks + +import ( + "testing" + + cetest "github.com/cloudevents/sdk-go/v2/test" + + "knative.dev/eventing/pkg/eventfilter/attributes" +) + +func BenchmarkAttributesFilter(b *testing.B) { + event := cetest.FullEvent() + + RunFilterBenchmarks(b, + FilterBenchmark{ + name: "Pass with exact match of id", + filter: attributes.NewAttributesFilter(map[string]string{"id": event.ID()}), + event: event, + }, + FilterBenchmark{ + // We don't test time because the exact match on the string apparently doesn't work well, + // which might cause the filter to fail. + name: "Pass with exact match of all context attributes (except time)", + filter: attributes.NewAttributesFilter(map[string]string{ + "id": event.ID(), + "source": event.Source(), + "type": event.Type(), + "dataschema": event.DataSchema(), + "datacontenttype": event.DataContentType(), + "subject": event.Subject(), + }), + event: event, + }, + FilterBenchmark{ + name: "No pass with exact match of id and source", + filter: attributes.NewAttributesFilter(map[string]string{"id": "qwertyuiopasdfghjklzxcvbnm", "source": "qwertyuiopasdfghjklzxcvbnm"}), + event: event, + }, + ) +} diff --git a/pkg/eventfilter/benchmarks/common_benchmark_test.go b/pkg/eventfilter/benchmarks/common_benchmark_test.go new file mode 100644 index 00000000000..26df41d7fbf --- /dev/null +++ b/pkg/eventfilter/benchmarks/common_benchmark_test.go @@ -0,0 +1,29 @@ +package benchmarks + +import ( + "context" + "testing" + + cloudevents "github.com/cloudevents/sdk-go/v2" + + "knative.dev/eventing/pkg/eventfilter" +) + +type FilterBenchmark struct { + name string + filter eventfilter.Filter + event cloudevents.Event +} + +// Avoid DCE +var R eventfilter.FilterResult + +func RunFilterBenchmarks(b *testing.B, filterBenchmarks ...FilterBenchmark) { + for _, fb := range filterBenchmarks { + b.Run(fb.name, func(b *testing.B) { + for i := 0; i < b.N; i++ { + R = fb.filter.Filter(context.TODO(), fb.event) + } + }) + } +} From 429c974fe17cf08619f3e036e500710ec9ef00c6 Mon Sep 17 00:00:00 2001 From: slinkydeveloper Date: Thu, 12 Nov 2020 15:13:24 +0100 Subject: [PATCH 2/6] Test Parse Signed-off-by: Francesco Guardiani --- .../benchmarks/attributes_benchmark_test.go | 23 ++++++++++++------- .../benchmarks/common_benchmark_test.go | 20 +++++++++++----- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/pkg/eventfilter/benchmarks/attributes_benchmark_test.go b/pkg/eventfilter/benchmarks/attributes_benchmark_test.go index 2c70a7dbfb7..eed8a30794e 100644 --- a/pkg/eventfilter/benchmarks/attributes_benchmark_test.go +++ b/pkg/eventfilter/benchmarks/attributes_benchmark_test.go @@ -5,6 +5,7 @@ import ( cetest "github.com/cloudevents/sdk-go/v2/test" + "knative.dev/eventing/pkg/eventfilter" "knative.dev/eventing/pkg/eventfilter/attributes" ) @@ -12,29 +13,35 @@ func BenchmarkAttributesFilter(b *testing.B) { event := cetest.FullEvent() RunFilterBenchmarks(b, + func(i interface{}) eventfilter.Filter { + return attributes.NewAttributesFilter(i.(map[string]string)) + }, FilterBenchmark{ - name: "Pass with exact match of id", - filter: attributes.NewAttributesFilter(map[string]string{"id": event.ID()}), - event: event, + name: "Pass with exact match of id", + arg: map[string]string{"id": event.ID()}, + event: event, }, FilterBenchmark{ // We don't test time because the exact match on the string apparently doesn't work well, // which might cause the filter to fail. name: "Pass with exact match of all context attributes (except time)", - filter: attributes.NewAttributesFilter(map[string]string{ + arg: map[string]string{ "id": event.ID(), "source": event.Source(), "type": event.Type(), "dataschema": event.DataSchema(), "datacontenttype": event.DataContentType(), "subject": event.Subject(), - }), + }, event: event, }, FilterBenchmark{ - name: "No pass with exact match of id and source", - filter: attributes.NewAttributesFilter(map[string]string{"id": "qwertyuiopasdfghjklzxcvbnm", "source": "qwertyuiopasdfghjklzxcvbnm"}), - event: event, + name: "No pass with exact match of id and source", + arg: map[string]string{ + "id": "qwertyuiopasdfghjklzxcvbnm", + "source": "qwertyuiopasdfghjklzxcvbnm", + }, + event: event, }, ) } diff --git a/pkg/eventfilter/benchmarks/common_benchmark_test.go b/pkg/eventfilter/benchmarks/common_benchmark_test.go index 26df41d7fbf..26684759ccd 100644 --- a/pkg/eventfilter/benchmarks/common_benchmark_test.go +++ b/pkg/eventfilter/benchmarks/common_benchmark_test.go @@ -10,19 +10,27 @@ import ( ) type FilterBenchmark struct { - name string - filter eventfilter.Filter - event cloudevents.Event + name string + arg interface{} + event cloudevents.Event } // Avoid DCE +var F eventfilter.Filter var R eventfilter.FilterResult -func RunFilterBenchmarks(b *testing.B, filterBenchmarks ...FilterBenchmark) { +func RunFilterBenchmarks(b *testing.B, filterCtor func(interface{}) eventfilter.Filter, filterBenchmarks ...FilterBenchmark) { for _, fb := range filterBenchmarks { - b.Run(fb.name, func(b *testing.B) { + b.Run("Parse: "+fb.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - R = fb.filter.Filter(context.TODO(), fb.event) + F = filterCtor(fb.arg) + } + }) + // Filter to use for the run + f := filterCtor(fb.arg) + b.Run("Run: "+fb.name, func(b *testing.B) { + for i := 0; i < b.N; i++ { + R = f.Filter(context.TODO(), fb.event) } }) } From d4d7556609def1997adf988345dce49bd2a4d112 Mon Sep 17 00:00:00 2001 From: slinkydeveloper Date: Thu, 12 Nov 2020 15:56:39 +0100 Subject: [PATCH 3/6] Name Signed-off-by: Francesco Guardiani --- pkg/eventfilter/benchmarks/common_benchmark_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/eventfilter/benchmarks/common_benchmark_test.go b/pkg/eventfilter/benchmarks/common_benchmark_test.go index 26684759ccd..1807765cbfb 100644 --- a/pkg/eventfilter/benchmarks/common_benchmark_test.go +++ b/pkg/eventfilter/benchmarks/common_benchmark_test.go @@ -21,7 +21,7 @@ var R eventfilter.FilterResult func RunFilterBenchmarks(b *testing.B, filterCtor func(interface{}) eventfilter.Filter, filterBenchmarks ...FilterBenchmark) { for _, fb := range filterBenchmarks { - b.Run("Parse: "+fb.name, func(b *testing.B) { + b.Run("Creation: "+fb.name, func(b *testing.B) { for i := 0; i < b.N; i++ { F = filterCtor(fb.arg) } From 68d521c616abdf062a23e3a7f5b6bb47d96f1d03 Mon Sep 17 00:00:00 2001 From: slinkydeveloper Date: Thu, 12 Nov 2020 16:00:02 +0100 Subject: [PATCH 4/6] Copyright Signed-off-by: Francesco Guardiani --- .../benchmarks/attributes_benchmark_test.go | 16 ++++++++++++++++ .../benchmarks/common_benchmark_test.go | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/pkg/eventfilter/benchmarks/attributes_benchmark_test.go b/pkg/eventfilter/benchmarks/attributes_benchmark_test.go index eed8a30794e..7aface791ee 100644 --- a/pkg/eventfilter/benchmarks/attributes_benchmark_test.go +++ b/pkg/eventfilter/benchmarks/attributes_benchmark_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2020 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package benchmarks import ( diff --git a/pkg/eventfilter/benchmarks/common_benchmark_test.go b/pkg/eventfilter/benchmarks/common_benchmark_test.go index 1807765cbfb..654fa4fd134 100644 --- a/pkg/eventfilter/benchmarks/common_benchmark_test.go +++ b/pkg/eventfilter/benchmarks/common_benchmark_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2020 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package benchmarks import ( From b0eda7d313873e70888708f172f4662a353a3cfc Mon Sep 17 00:00:00 2001 From: slinkydeveloper Date: Thu, 12 Nov 2020 16:56:37 +0100 Subject: [PATCH 5/6] Rename Signed-off-by: Francesco Guardiani --- pkg/eventfilter/benchmarks/common_benchmark_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/eventfilter/benchmarks/common_benchmark_test.go b/pkg/eventfilter/benchmarks/common_benchmark_test.go index 654fa4fd134..0635bc1330a 100644 --- a/pkg/eventfilter/benchmarks/common_benchmark_test.go +++ b/pkg/eventfilter/benchmarks/common_benchmark_test.go @@ -32,21 +32,21 @@ type FilterBenchmark struct { } // Avoid DCE -var F eventfilter.Filter -var R eventfilter.FilterResult +var Filter eventfilter.Filter +var Result eventfilter.FilterResult func RunFilterBenchmarks(b *testing.B, filterCtor func(interface{}) eventfilter.Filter, filterBenchmarks ...FilterBenchmark) { for _, fb := range filterBenchmarks { b.Run("Creation: "+fb.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - F = filterCtor(fb.arg) + Filter = filterCtor(fb.arg) } }) // Filter to use for the run f := filterCtor(fb.arg) b.Run("Run: "+fb.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - R = f.Filter(context.TODO(), fb.event) + Result = f.Filter(context.TODO(), fb.event) } }) } From 4a0db25b0ea1daa7e09dda1e7607f30d39c9e2ca Mon Sep 17 00:00:00 2001 From: slinkydeveloper Date: Thu, 12 Nov 2020 17:04:59 +0100 Subject: [PATCH 6/6] Comment Signed-off-by: Francesco Guardiani --- pkg/eventfilter/benchmarks/common_benchmark_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/eventfilter/benchmarks/common_benchmark_test.go b/pkg/eventfilter/benchmarks/common_benchmark_test.go index 0635bc1330a..793dc2103b0 100644 --- a/pkg/eventfilter/benchmarks/common_benchmark_test.go +++ b/pkg/eventfilter/benchmarks/common_benchmark_test.go @@ -35,6 +35,9 @@ type FilterBenchmark struct { var Filter eventfilter.Filter var Result eventfilter.FilterResult +// RunFilterBenchmarks executes 2 benchmark runs for each of the provided bench cases: +// 1. "Creation: ..." benchmark measures the time/mem to create the filter, given the filter constructor and the argument +// 2. "Run: ..." benchmark measures the time/mem to execute the filter, given a pre-built filter instance and the provided event func RunFilterBenchmarks(b *testing.B, filterCtor func(interface{}) eventfilter.Filter, filterBenchmarks ...FilterBenchmark) { for _, fb := range filterBenchmarks { b.Run("Creation: "+fb.name, func(b *testing.B) {