-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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: generate same code regardless of whether return values are named #20859
Comments
I like named return values. I wish I had permission to use them. -rob |
I interpret this as sadness about the "style" URL above, another term I know you don't like. I guess you value anti-stutter in godoc differently than some of us do. I agree there are cases where it'd be nice to use named return values (especially to reference them from defer) without cluttering godoc. Or to eliminate a few lines in other cases. It'd be neat if we could influence godoc rendering separate from whether we chose to use named return values in code. But those proposals never go anywhere quickly (#16666, #18342, #7873), so instead we control documentation formatting by how we write the code. |
Is this issue about the following two styles generating same code? func foo() (ch credentialHeader) {
// ...
if cond {
return ch
}
// ...
return ch
} func foo() credentialHeader {
var ch credentialHeader
// ...
if cond {
return ch
}
// ...
return ch
} Or is it about handling these cases too? func foo() credentialHeader {
// ...
if cond {
return credentialHeader{/* ... */}
}
// ...
return credentialHeader{/* ... */}
} |
It would be great if the compiler can take care of this and always generated the most optimal code. Even so, for all of the examples as posted above by @shurcooL, you can still argue that the first is the most readable (or at the very least it is the briefest version). But of course this also has to do with personal style. |
Sometimes, such as when there are several return values , code can be cleaner and simpler using named returns. One instance is when there are multiple return values followed by an error: you can use Go's handling of zero values on function entry to avoid messy return statements. But the style guys win, they always win, and much as I like consistency in the code base I get sad when following the style guide makes the code uglier. The style tyrants made illegal the single most interesting language property of Sawzall because to use it required judgment. The language was made much clumsier in practice as a result, and it depressed me. Style tyrants want to eliminate judgment, plus it seems sometimes that the result of style guides is to steer programmers away from all the interesting properties of the language, towards a mainstream but dull uniformity free of joy. I follow the style guide anyway, just to be clear. |
Maybe, if someone has poor judgment, it is better to stay away from writing code altogether (or doing other stuff for that matter...) And besides, hey, where would be the world be without some rebellions... 😄 |
@robpike - pray tell, which feature was that? |
It seems there are a few things for the binary difference. In the first example in the blog,
The compiler generates four separate statictmps for If I rewrite it to something like (like @shurcooL's example)
It generates
So it makes a zero-valued local variable |
@robpike I use named return values, even though I lack permission. |
Some minor observations.
So while the compiler doesn't do well on the example given, and should be improved, it's not obvious to me that named and unnamed returns should always generate the same code. And in fact, I'd think using unnamed returns should always be a pareto performance improvement on named returns, since using named returns ties the compiler's hands in a way that unnamed returns do not. But, with @robpike, the primary consideration should be a judgment call about the readability of the code anyway. Except where critical to performance, there is significant danger of overfitting the compiler.
Agreed on both counts. I'm surprised that there is a statictmp for this; I thought sinit was pretty good about recognizing zero values.
Yes, although why should it copy instead of just zeroing?
Seems to me like that is the crux of this issue, although I'm not sure how feasible that is to implement. |
Just a few remarks:
Looking at
just like in
(and looking at
Agreed, when using a named return value its content can be modified, so it is not possible to rely on the fact that it is not modified, so for a
Would think that this actually makes it easier, especially in combination with naked |
Not likely for 1.11, moved to 1.12. |
Nor is it likely for Go1.12, I am moving this to Go1.13 /cc @randall77 |
I just hit this again when I sent https://go-review.googlesource.com/c/go/+/322329 to clean up some inconsistent godoc and it instead increased the size of stacks. |
@bradfitz I think CL 322329 is a slightly different issue? I understand this issue to be that if a function has a named result parameter, but the name isn't used, then it should compile identically to if it was anonymous or blank instead. However, that CL not only removed the result parameter names, but also added new local variables to replace them. In that particular case, we could optimize the code to directly allocate the |
I wonder whether we could use space reserved for unnamed return parameters as scratch space (assuming compatible types). That'd probably fix this mismatch and be a bonus optimization in other cases. cc @dr2chase |
@josharian I think as long as panic and defer are handled correctly, that seems reasonable. I'd suggest as a starting point to not attempt that optimization in any function that contains a defer statement. |
Change https://golang.org/cl/361674 mentions this issue: |
name old time/op new time/op delta As16-8 2.88ns ± 3% 2.16ns ± 3% -25.19% (p=0.000 n=15+15) Fixes #49379 Updates #20859 Change-Id: If4cf58d19ed0e2ac0f179da5c132ed37061e4cb7 Reviewed-on: https://go-review.googlesource.com/c/go/+/361674 Trust: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
There's an article at the top of Hacker News right now,
https://blog.minio.io/golang-internals-part-2-nice-benefits-of-named-return-values-1e95305c8687
https://news.ycombinator.com/item?id=14668323
... which advocates for naming return values for the benefit of better generated code.
It concludes:
This is totally counter to:
https://golang.org/s/style#named-result-parameters
... which says that naming result parameters should only be for godoc cleanliness.
We should fix the compiler to generate the same code regardless.
/cc @randall77 @mdempsky @josharian @brtzsnr @cherrymui
The text was updated successfully, but these errors were encountered: