diff options
| author | Cuong Manh Le <cuong.manhle.vn@gmail.com> | 2025-02-25 23:59:14 +0700 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2025-02-25 12:23:56 -0800 |
| commit | 8203265d5eef37bf41d7d2df126f77ebd5abc999 (patch) | |
| tree | 338cd9d6399cadfa660468fddf4a943bee81f4bb /src/runtime/string.go | |
| parent | beb314c0dbcbe03b576123e99e1331348f858ecc (diff) | |
| download | go-8203265d5eef37bf41d7d2df126f77ebd5abc999.tar.xz | |
cmd/compile, runtime: optimize concatbytes
CL 527935 optimized []byte(string1 + string2) to use runtime.concatbytes
to prevent concatenating of strings before converting to slices.
However, the optimization is implemented without allowing temporary
buffer for slice on stack, causing un-necessary allocations.
To fix this, optimize concatbytes to use temporary buffer if the result
string length fit to the buffer size.
Fixes #71943
Change-Id: I1d3c374cd46aad8f83a271b8a5ca79094f9fd8db
Reviewed-on: https://go-review.googlesource.com/c/go/+/652395
Reviewed-by: Keith Randall <khr@google.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
Diffstat (limited to 'src/runtime/string.go')
| -rw-r--r-- | src/runtime/string.go | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/src/runtime/string.go b/src/runtime/string.go index e43f4cca51..7bb9d58de0 100644 --- a/src/runtime/string.go +++ b/src/runtime/string.go @@ -76,7 +76,7 @@ func concatstring5(buf *tmpBuf, a0, a1, a2, a3, a4 string) string { // concatbytes implements a Go string concatenation x+y+z+... returning a slice // of bytes. // The operands are passed in the slice a. -func concatbytes(a []string) []byte { +func concatbytes(buf *tmpBuf, a []string) []byte { l := 0 for _, x := range a { n := len(x) @@ -90,7 +90,13 @@ func concatbytes(a []string) []byte { return []byte{} } - b := rawbyteslice(l) + var b []byte + if buf != nil && l <= len(buf) { + *buf = tmpBuf{} + b = buf[:l] + } else { + b = rawbyteslice(l) + } offset := 0 for _, x := range a { copy(b[offset:], x) @@ -100,20 +106,20 @@ func concatbytes(a []string) []byte { return b } -func concatbyte2(a0, a1 string) []byte { - return concatbytes([]string{a0, a1}) +func concatbyte2(buf *tmpBuf, a0, a1 string) []byte { + return concatbytes(buf, []string{a0, a1}) } -func concatbyte3(a0, a1, a2 string) []byte { - return concatbytes([]string{a0, a1, a2}) +func concatbyte3(buf *tmpBuf, a0, a1, a2 string) []byte { + return concatbytes(buf, []string{a0, a1, a2}) } -func concatbyte4(a0, a1, a2, a3 string) []byte { - return concatbytes([]string{a0, a1, a2, a3}) +func concatbyte4(buf *tmpBuf, a0, a1, a2, a3 string) []byte { + return concatbytes(buf, []string{a0, a1, a2, a3}) } -func concatbyte5(a0, a1, a2, a3, a4 string) []byte { - return concatbytes([]string{a0, a1, a2, a3, a4}) +func concatbyte5(buf *tmpBuf, a0, a1, a2, a3, a4 string) []byte { + return concatbytes(buf, []string{a0, a1, a2, a3, a4}) } // slicebytetostring converts a byte slice to a string. |
