New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd/compile: use slicebytetostringtmp in concatenation #31993
Comments
IRC the compiler uses slicebytetostringtmp for concats if one of the non converted string concats is known to be non zero as there is an optimization that does not copy the content of the string if all other arguments of concat have zero length. We could (and I had thought about that too after optimizing it by hand in real code) optimize string concats which are only in comparison. So generally e.g. string(a) + string(b) ...== string(c) + string(d) ... . Is the real program mentioned also using concat in a comparison? |
Good point.
No, it wasn't in comparison. The string is parsed further and memorized in an escaping struct. |
You could try optimizing using e.g. (“a”+string(data)+str)[1:] to trigger slicebytetostringtmp until we find a nicer way for the compiler to understand that neither data nor str can be empty by e.g. using information from the prove pass for bounds checks and an additional length check in the code. Alternatively like in this case we could make the compiler use a special concat call that always copies but also avoids all string allocations for string conversions. |
One option here is that if the compiler can't prove that any of the strings are non-empty, it could just pass that information on to the runtime, so the runtime knows it can't do the return-without-copying optimization. E.g., it could provide a uintptr bitset representing which string operands used slicebytetostringtmp. The runtime then just needs to do a single bit test to figure out if the optimization is safe. (And conservatively, we can't use slicebytetostringtmp for arguments past the first 32 or 64, depending on ptr-size, unless we know there's a non-empty string operand.) |
$ go version
go version devel +2e4edf4697 Sun May 12 07:14:09 2019 +0000 linux/amd64
Test:
This currently uses runtime.slicebytetostring followed by runtime.concatstring2. I think this could use runtime.slicebytetostringtmp for slice->string conversion.
This is extracted from a real program where the slice is large, but we need to append a small string to it. Avoiding the second alloc/copy would be useful.
The text was updated successfully, but these errors were encountered: