1
0
mirror of https://github.com/golang/go synced 2024-09-30 12:08:32 -06:00

strings: reuse input string for Repeat count of 1

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)
This commit is contained in:
Anuraag Agrawal 2022-06-10 14:18:43 +09:00
parent 2cfbef4380
commit 068f58e08b
2 changed files with 5 additions and 2 deletions

View File

@ -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,

View File

@ -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)