From 068f58e08b8f5c4105e7a210f242ca1ff3a61177 Mon Sep 17 00:00:00 2001 From: Anuraag Agrawal Date: Fri, 10 Jun 2022 14:18:43 +0900 Subject: [PATCH] strings: reuse input string for Repeat count of 1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing implementation allocates a new string even when the count is 1, where we know the output is the same as the input. While we wouldn't expect a count of 1 for hardcoded values of the parameter, it is expected when the parameter is computed based on a different value (e.g., the length of a input slice). name old time/op new time/op delta Repeat/5x0-10 2.03ns ± 0% 2.02ns ± 0% ~ (p=1.000 n=1+1) Repeat/5x1-10 13.7ns ± 0% 2.0ns ± 0% ~ (p=1.000 n=1+1) Repeat/5x2-10 18.2ns ± 0% 18.1ns ± 0% ~ (p=1.000 n=1+1) Repeat/5x6-10 27.0ns ± 0% 27.0ns ± 0% ~ (p=1.000 n=1+1) Repeat/10x0-10 2.02ns ± 0% 2.02ns ± 0% ~ (p=1.000 n=1+1) Repeat/10x1-10 16.1ns ± 0% 2.0ns ± 0% ~ (p=1.000 n=1+1) Repeat/10x2-10 20.8ns ± 0% 20.9ns ± 0% ~ (p=1.000 n=1+1) Repeat/10x6-10 29.2ns ± 0% 29.4ns ± 0% ~ (p=1.000 n=1+1) --- src/strings/strings.go | 5 ++++- src/strings/strings_test.go | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/strings/strings.go b/src/strings/strings.go index 1dc4238522..d9c8936fc8 100644 --- a/src/strings/strings.go +++ b/src/strings/strings.go @@ -526,8 +526,11 @@ func Map(mapping func(rune) rune, s string) string { // It panics if count is negative or if // the result of (len(s) * count) overflows. func Repeat(s string, count int) string { - if count == 0 { + switch count { + case 0: return "" + case 1: + return s } // Since we cannot return an error on overflow, diff --git a/src/strings/strings_test.go b/src/strings/strings_test.go index 9e7fb85ddf..1cda6546d0 100644 --- a/src/strings/strings_test.go +++ b/src/strings/strings_test.go @@ -1807,7 +1807,7 @@ func BenchmarkSplitNMultiByteSeparator(b *testing.B) { func BenchmarkRepeat(b *testing.B) { s := "0123456789" for _, n := range []int{5, 10} { - for _, c := range []int{1, 2, 6} { + for _, c := range []int{0, 1, 2, 6} { b.Run(fmt.Sprintf("%dx%d", n, c), func(b *testing.B) { for i := 0; i < b.N; i++ { Repeat(s[:n], c)