aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/string.go
diff options
context:
space:
mode:
authorCuong Manh Le <cuong.manhle.vn@gmail.com>2025-02-25 23:59:14 +0700
committerGopher Robot <gobot@golang.org>2025-02-25 12:23:56 -0800
commit8203265d5eef37bf41d7d2df126f77ebd5abc999 (patch)
tree338cd9d6399cadfa660468fddf4a943bee81f4bb /src/runtime/string.go
parentbeb314c0dbcbe03b576123e99e1331348f858ecc (diff)
downloadgo-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.go26
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.