diff --git a/src/strings/strings.go b/src/strings/strings.go index adbbe742fc..a0a31f7c58 100644 --- a/src/strings/strings.go +++ b/src/strings/strings.go @@ -541,17 +541,26 @@ func Repeat(s string, count int) string { // See Issue golang.org/issue/16237 if count < 0 { panic("strings: negative Repeat count") - } else if count > 0 && len(s)*count/count != len(s) { + } else if count == 0 { + return "" + } else if len(s)*count/count != len(s) { panic("strings: Repeat count causes overflow") } - b := make([]byte, len(s)*count) - bp := copy(b, s) - for bp < len(b) { - copy(b[bp:], b[:bp]) - bp *= 2 + k, n := len(s), len(s)*count + var b Builder + b.Grow(n) + b.WriteString(s) + for k < n { + if k + k < n { + b.WriteString(b.String()) + k = k + k + } else { + b.WriteString(b.String()[:n-k]) + break + } } - return string(b) + return b.String() } // ToUpper returns a copy of the string s with all Unicode letters mapped to their upper case. diff --git a/src/strings/strings_test.go b/src/strings/strings_test.go index 78bc573e5f..ffc4ab0964 100644 --- a/src/strings/strings_test.go +++ b/src/strings/strings_test.go @@ -1648,7 +1648,21 @@ func BenchmarkSplitNMultiByteSeparator(b *testing.B) { func BenchmarkRepeat(b *testing.B) { for i := 0; i < b.N; i++ { - Repeat("-", 80) + b.Run("length-1", func(b *testing.B) { + for i := 0; i < b.N; i++ { + Repeat("-", 80) + } + }) + b.Run("length-5", func(b *testing.B) { + for i := 0; i < b.N; i++ { + Repeat("-!@#$", 80) + } + }) + b.Run("length-10", func(b *testing.B) { + for i := 0; i < b.N; i++ { + Repeat("-!@#$abcde", 80) + } + }) } }