aboutsummaryrefslogtreecommitdiff
path: root/src/strings
diff options
context:
space:
mode:
Diffstat (limited to 'src/strings')
-rw-r--r--src/strings/strings.go24
-rw-r--r--src/strings/strings_test.go11
2 files changed, 26 insertions, 9 deletions
diff --git a/src/strings/strings.go b/src/strings/strings.go
index 97d83cfde1..e0bebced63 100644
--- a/src/strings/strings.go
+++ b/src/strings/strings.go
@@ -523,23 +523,33 @@ 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 {
+ return ""
+ }
+
// Since we cannot return an error on overflow,
// we should panic if the repeat will generate
// an overflow.
// 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 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
+ n := len(s) * count
+ var b Builder
+ b.Grow(n)
+ b.WriteString(s)
+ for b.Len() < n {
+ if b.Len() <= n/2 {
+ b.WriteString(b.String())
+ } else {
+ b.WriteString(b.String()[:n-b.Len()])
+ 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 bb46e136f2..d6197ed895 100644
--- a/src/strings/strings_test.go
+++ b/src/strings/strings_test.go
@@ -1660,8 +1660,15 @@ func BenchmarkSplitNMultiByteSeparator(b *testing.B) {
}
func BenchmarkRepeat(b *testing.B) {
- for i := 0; i < b.N; i++ {
- Repeat("-", 80)
+ s := "0123456789"
+ for _, n := range []int{5, 10} {
+ for _, c := range []int{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)
+ }
+ })
+ }
}
}