-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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: skip slicebytetostring when argument doesn't escape #6714
Comments
I've poked at this a bit and wanted to get some feedback before I continued. As written, hi only allocs once, since b is allocated on the stack. A quick benchmem run bears this out. If b's cap is much larger or unknown at compile time, then yes, two allocs occur. I cobbled together a very crude patch that returns a string header in case cases, as suggested. It is possibly underpowered, but it found only a few opportunities in the stdlib for such an optimization: strings/replace.go:502 strings/strings.go:367 strings/strings.go:430 strconv/quote.go:82 strconv/quote.go:349 encoding/base64/base64.go:121 os/env.go:26 path/filepath/path.go:314 net/url/url.go:168 net/url/url.go:211 Running the existing benchmarks, the only alloc count improvements are: strings BenchmarkByteStringMatch: 2 -> 1 strings BenchmarkHTMLEscapeNew: 2 -> 1 strings BenchmarkCountTortureOverlapping: 4 -> 2 strconv BenchmarkUnquoteHard: 2 -> 1 net/url BenchmarkString: 44 -> 39 Extending to rune slices adds only two call sites: compress/gzip/gunzip.go:118 testing/quick/quick.go:127 I'd need non-trivial direction and input to bring my patch up to snuff...or more likely, rewrite it from scratch after some hints. (I am finding my way by touch; all the tests pass, though, so that's something.) Given all the above, should I continue to pursue this? |
Maybe this should change the milestone to 1.7? |
No, this isn't critical to 1.7 or any particular release. This is not a regression or anything. |
We already had special cases for 0 and 1. Add 2 and 3 for now too. To be removed if the compiler is improved later (#6714). This halves the number of allocations and total bytes allocated via common filepath.Join calls, improving filepath.Walk performance. Noticed as part of investigating filepath.Walk in #16399. Change-Id: If7b1bb85606d4720f3ebdf8de7b1e12ad165079d Reviewed-on: https://go-review.googlesource.com/25005 Reviewed-by: Ian Lance Taylor <[email protected]> Run-TryBot: Brad Fitzpatrick <[email protected]>
If this is fixed, revert https://golang.org/cl/25005 |
Is anyone working on this? I'd be interested in trying to fix it, though I've never worked on the compiler part of this project before. |
I don't think anyone is working on it. |
Note that "b does not escape" is not a sufficient condition. The real question is "is this the only reference to b's backing array?", which is a related but different question. For example, func hi() string {
b := make([]byte, 0, 100) // 1st alloc
b = append(b, "Hello, "...)
b = append(b, "world.\n"...)
s := string(b)
b[0] = 'X'
return s
} b does not escape here, but it's not safe to use stringtoslicebytetmp because b's backing array is still reachable from the stack. This may be a liveness question, not an escape question. If the last point b's backing array is live is at the string conversion, then it should be safe to reuse it. |
CL https://golang.org/cl/27327 mentions this issue. |
I'm going to take another crack at this this week. |
OK but too late for Go 1.8. We'll review what you send when we get to Go 1.9. |
Understood! I still need to get up to speed with e.g. "how to figure out whether a variable escapes" but there has never been a better time to learn. |
See also: #18990 |
@rsc it's late for Go 1.9 too :) |
is there any news on this? |
@JAicewizard I think it was postponed because of the introduction of |
Seem fixed: https://play.golang.org/p/koSvIIvUnRs |
Small fixed length slices that do not escape are allocated on the stack. I think this has been for a while. Having a variable byte slice and then a string conversion as far as I know still causes two heap allocations if the resulting string escapes even if there are no other references to the byte slice. |
The text was updated successfully, but these errors were encountered: