-
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
crypto/elliptic: regression from 1.17 in the cost of parsing and compiling p256_asm_table.go #50995
Comments
Labeling release-blocker for assessment before Go 1.18. |
Users are probably never gofmt-ing this code. Maybe some code analysis tools parse it though? Does vet parse it, or does it use object files? |
Running gofmt on the entire standard library seems like a reasonable thing to do, for example when testing that a change to gofmt isn't resulting in unexpected changes. I don't see a reason why that should burn CPU for a solid second if we can avoid it :) You're right that the build cache partially hides this slow-down from many users, but it's still noticeable whenever the standard library is rebuilt. This will be the case for cross-builds, when build parameters like build tags are changed, when building Go itself from source (which I do on a daily basis), or with |
I should note that we have two rather easy fixes at hand, here, with presumably no downsides. I would perhaps agree with Keith if there was a significant downside to the changes. |
Not release team, but change Looks Safe To Me at least. Can you file & make the commit reference a bug for the root problem in any case? The compiler & gofmt shouldn't be so sensitive to this. |
I did think about whether gofmt and the compiler are to blame for this, but I'm not so sure we can blame them; a syntax tree with a chain of tens of thousands of nodes will be slow no matter what, because you'll need to jump through tens of thousands of pointers to traverse it. I guess one fix would be "make The compiler could potentially prevent the slow-down, because it doesn't publicly expose its syntax tree representation, though I'm not sure whether remedying this slow-down in the compiler and not all other tools will be worthwhile. Even if the builds are fast, all other tooling including gofmt would still be slow. cc @griesemer @josharian could you please confirm whether the |
And also, thinking outloud: I'm not sure we need to worry too much about Go files that have ten thousand string additions chained together, because I've only seen that in generated code to embed some form of asset - and, presumably, all of those can just switch to |
Apologies for the delay. Both CLs look fine to me, both from a code perspective and from a binary properties perspective. The compiler has special handling for long string constant concatenation, for #16394. See go/src/cmd/compile/internal/noder/noder.go Lines 837 to 840 in 911c78f
But perhaps that is broken? Or there is another place we need that fix? Regardless of what we do about |
Thank you! I'll tidy up the |
Change https://go.dev/cl/380475 mentions this issue: |
I had some spare time, and I didn't want to delay a release blocker, so the |
Could someone please confirm that this is an OK change to make in deps_test.go? embed is a tiny package, and crypto/elliptic is already manually embedding a file via code generation, so I don't imagine it should cause any problems. |
I think it's fine for crypto/elliptic to depend on embed. |
Change https://go.dev/cl/383995 mentions this issue: |
go:embed disallows using symlinked files by design. crypto/elliptic is the first std package to use it as of CL 380475, and unfortunately that broke the TestRepeatBootstrap long test. The reason it uses symlinks is for speed; it wants to copy GOROOT/src, but regular files aren't going to be modified in any way, so a symlink, if supported, means not needing to copy the contents. Replace the symlink attempt with hard links, which will mean regular files remain as such, fixing go:embed. It's worth noting that on many systems hard links won't work, as the temporary filesystem tends to be separate, but it doesn't hurt to try. In my system, where /tmp is tmpfs, the test now copies more bytes. With the added Logf, I can see overlayDir goes from ~30ms to ~100ms. This makes sense, as GOROOT/src currently weighs around 100MiB. To alleviate that slow-down, stop copying testdata directories, as they currently weigh around 20MiB and aren't needed for the test. This gets overlayDir on my system down to an acceptable ~70ms. I briefly considered teaching overlayDir what files can be symlinks, but that seemed fairly complex long-term, as any file could be embedded. While here, start using testing.T.TempDir and fs.WalkDir. For #50995. Change-Id: I17947e6bdee96237e1ca0606ad0b95e7c5987bc1 Reviewed-on: https://go-review.googlesource.com/c/go/+/383995 Trust: Daniel Martí <mvdan@mvdan.cc> Trust: Bryan Mills <bcmills@google.com> Run-TryBot: Bryan Mills <bcmills@google.com> Reviewed-by: Bryan Mills <bcmills@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
Please see https://go-review.googlesource.com/c/go/+/380474 for details. I'm opening this issue so we can track this for the 1.18 release.
In short, https://go-review.googlesource.com/c/go/+/339591/ changed the code generator, and since then, that file is significantly more expensive to parse and compile due to the extensive use of binary expressions:
https://go-review.googlesource.com/c/go/+/380474 fixes this issue by using fewer binary expressions, and https://go-review.googlesource.com/c/go/+/380475 fixes this by using
go:embed
.I don't really mind which of the two we pick, but I really think we need a fix before the final release, as the regression seems pretty significant. I don't think this affects compiled code, but it certainly affects the developer experience through build speed and tool speed.
cc @josharian @rolandshoemaker @FiloSottile @bcmills
The text was updated successfully, but these errors were encountered: