From 2dba5dbf86866a327b1dec3a8ee3d83a68daeef5 Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Thu, 9 Jan 2020 21:14:01 +0530 Subject: [PATCH] MM-21368: Optimize MapStringsToQueryParams (#13601) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use strings.Builder which minimizes allocations. - Avoid fmt.Sprintf which is slower than simple string concat. Results: name old time/op new time/op delta MapStringsToQueryParams/one_item-8 512ns ± 2% 377ns ± 1% -26.27% (p=0.000 n=10+9) MapStringsToQueryParams/multiple_items-8 858ns ± 5% 748ns ± 2% -12.82% (p=0.000 n=10+9) name old alloc/op new alloc/op delta MapStringsToQueryParams/one_item-8 456B ± 0% 384B ± 0% -15.79% (p=0.000 n=10+9) MapStringsToQueryParams/multiple_items-8 608B ± 0% 592B ± 0% -2.63% (p=0.000 n=10+10) name old allocs/op new allocs/op delta MapStringsToQueryParams/one_item-8 8.00 ± 0% 6.00 ± 0% -25.00% (p=0.000 n=10+10) MapStringsToQueryParams/multiple_items-8 12.0 ± 0% 12.0 ± 0% ~ (all equal) --- store/sqlstore/utils.go | 6 ++---- store/sqlstore/utils_test.go | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/store/sqlstore/utils.go b/store/sqlstore/utils.go index 4018a17a65..1ca8f1fe70 100644 --- a/store/sqlstore/utils.go +++ b/store/sqlstore/utils.go @@ -4,9 +4,7 @@ package sqlstore import ( - "bytes" "database/sql" - "fmt" "strconv" "strings" @@ -32,7 +30,7 @@ func sanitizeSearchTerm(term string, escapeChar string) string { // Converts a list of strings into a list of query parameters and a named parameter map that can // be used as part of a SQL query. func MapStringsToQueryParams(list []string, paramPrefix string) (string, map[string]interface{}) { - keys := bytes.Buffer{} + var keys strings.Builder params := make(map[string]interface{}, len(list)) for i, entry := range list { if keys.Len() > 0 { @@ -44,7 +42,7 @@ func MapStringsToQueryParams(list []string, paramPrefix string) (string, map[str params[key] = entry } - return fmt.Sprintf("(%v)", keys.String()), params + return "(" + keys.String() + ")", params } // finalizeTransaction ensures a transaction is closed after use, rolling back if not already committed. diff --git a/store/sqlstore/utils_test.go b/store/sqlstore/utils_test.go index e7c6bdce2d..7db47c61ac 100644 --- a/store/sqlstore/utils_test.go +++ b/store/sqlstore/utils_test.go @@ -33,6 +33,24 @@ func TestMapStringsToQueryParams(t *testing.T) { }) } +var keys string +var params map[string]interface{} + +func BenchmarkMapStringsToQueryParams(b *testing.B) { + b.Run("one item", func(b *testing.B) { + input := []string{"apple"} + for i := 0; i < b.N; i++ { + keys, params = MapStringsToQueryParams(input, "Fruit") + } + }) + b.Run("multiple items", func(b *testing.B) { + input := []string{"carrot", "tomato", "potato"} + for i := 0; i < b.N; i++ { + keys, params = MapStringsToQueryParams(input, "Vegetable") + } + }) +} + func TestSanitizeSearchTerm(t *testing.T) { term := "test" result := sanitizeSearchTerm(term, "\\")