aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIgnacio Hagopian <jsign.uy@gmail.com>2021-08-17 23:52:00 +0000
committerRobert Griesemer <gri@golang.org>2021-08-22 23:49:55 +0000
commit86ee89225aea2326fd50dbeb233cfc622413a4cf (patch)
tree370a1847d84bd36d596af360ebdd37a3af6cba58 /src
parent29d7e5472be79b77f39d81b697d44038179ba1a1 (diff)
downloadgo-86ee89225aea2326fd50dbeb233cfc622413a4cf.tar.gz
go-86ee89225aea2326fd50dbeb233cfc622413a4cf.zip
strings: smarter growth of temporal buffer and avoid copying on return
The implementation for single strings had two optimization opportunities: 1. Grow the temporary buffer by known size before appending. 2. Avoid a full copy of the result since the underlying buffer won't be mutated afterward. Both things were leveraged by using a Builder instead of a byte slice. Relevant benchmark results: name old time/op new time/op delta SingleMatch-8 32.0µs ± 3% 26.1µs ± 3% -18.41% (p=0.000 n=9+10) name old speed new speed delta SingleMatch-8 469MB/s ± 3% 574MB/s ± 3% +22.56% (p=0.000 n=9+10) name old alloc/op new alloc/op delta SingleMatch-8 81.3kB ± 0% 49.0kB ± 0% -39.67% (p=0.000 n=10+10) name old allocs/op new allocs/op delta SingleMatch-8 19.0 ± 0% 11.0 ± 0% -42.11% (p=0.000 n=10+10) Change-Id: I23af56a15875206c0ff4ce29a51bec95fd48bb11 GitHub-Last-Rev: 403cfc3c2794b5da27792c51999417a2a052b365 GitHub-Pull-Request: golang/go#47766 Reviewed-on: https://go-review.googlesource.com/c/go/+/343089 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> Trust: Robert Griesemer <gri@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/strings/replace.go11
1 files changed, 6 insertions, 5 deletions
diff --git a/src/strings/replace.go b/src/strings/replace.go
index e28d428879..ee728bb22b 100644
--- a/src/strings/replace.go
+++ b/src/strings/replace.go
@@ -387,7 +387,7 @@ func makeSingleStringReplacer(pattern string, value string) *singleStringReplace
}
func (r *singleStringReplacer) Replace(s string) string {
- var buf []byte
+ var buf Builder
i, matched := 0, false
for {
match := r.finder.next(s[i:])
@@ -395,15 +395,16 @@ func (r *singleStringReplacer) Replace(s string) string {
break
}
matched = true
- buf = append(buf, s[i:i+match]...)
- buf = append(buf, r.value...)
+ buf.Grow(match + len(r.value))
+ buf.WriteString(s[i : i+match])
+ buf.WriteString(r.value)
i += match + len(r.finder.pattern)
}
if !matched {
return s
}
- buf = append(buf, s[i:]...)
- return string(buf)
+ buf.WriteString(s[i:])
+ return buf.String()
}
func (r *singleStringReplacer) WriteString(w io.Writer, s string) (n int, err error) {