Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions src/strings/strings.go
Original file line number Diff line number Diff line change
Expand Up @@ -535,23 +535,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.
Expand Down
11 changes: 9 additions & 2 deletions src/strings/strings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1647,8 +1647,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)
}
})
}
}
}

Expand Down