From: Rui Ueyama Date: Thu, 12 Jun 2014 02:03:59 +0000 (-0700) Subject: bytes, strings: optimize Repeat X-Git-Tag: go1.4beta1~1313 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=7bcbb65d7879f17b185cee9ab4ab392da0bd865f;p=gostls13.git bytes, strings: optimize Repeat Call copy with as large buffer as possible to reduce the number of function calls. benchmark old ns/op new ns/op delta BenchmarkBytesRepeat 540 162 -70.00% BenchmarkStringsRepeat 563 177 -68.56% LGTM=josharian R=golang-codereviews, josharian, dave, dvyukov CC=golang-codereviews https://golang.org/cl/90550043 --- diff --git a/src/pkg/bytes/bytes.go b/src/pkg/bytes/bytes.go index 0c53e4c0b7..d8b6f998b3 100644 --- a/src/pkg/bytes/bytes.go +++ b/src/pkg/bytes/bytes.go @@ -377,9 +377,10 @@ func Map(mapping func(r rune) rune, s []byte) []byte { // Repeat returns a new byte slice consisting of count copies of b. func Repeat(b []byte, count int) []byte { nb := make([]byte, len(b)*count) - bp := 0 - for i := 0; i < count; i++ { - bp += copy(nb[bp:], b) + bp := copy(nb, b) + for bp < len(nb) { + copy(nb[bp:], nb[:bp]) + bp *= 2 } return nb } diff --git a/src/pkg/bytes/bytes_test.go b/src/pkg/bytes/bytes_test.go index 394dd7a443..980c41d754 100644 --- a/src/pkg/bytes/bytes_test.go +++ b/src/pkg/bytes/bytes_test.go @@ -1232,3 +1232,9 @@ func BenchmarkTrimSpace(b *testing.B) { TrimSpace(s) } } + +func BenchmarkRepeat(b *testing.B) { + for i := 0; i < b.N; i++ { + Repeat([]byte("-"), 80) + } +} diff --git a/src/pkg/strings/strings.go b/src/pkg/strings/strings.go index 5d46211d84..53bcd6b98a 100644 --- a/src/pkg/strings/strings.go +++ b/src/pkg/strings/strings.go @@ -423,9 +423,10 @@ func Map(mapping func(rune) rune, s string) string { // Repeat returns a new string consisting of count copies of the string s. func Repeat(s string, count int) string { b := make([]byte, len(s)*count) - bp := 0 - for i := 0; i < count; i++ { - bp += copy(b[bp:], s) + bp := copy(b, s) + for bp < len(b) { + copy(b[bp:], b[:bp]) + bp *= 2 } return string(b) } diff --git a/src/pkg/strings/strings_test.go b/src/pkg/strings/strings_test.go index e40a18015e..95102b56fa 100644 --- a/src/pkg/strings/strings_test.go +++ b/src/pkg/strings/strings_test.go @@ -1174,3 +1174,9 @@ func BenchmarkSplit3(b *testing.B) { Split(benchInputHard, "hello") } } + +func BenchmarkRepeat(b *testing.B) { + for i := 0; i < b.N; i++ { + Repeat("-", 80) + } +}