-
Notifications
You must be signed in to change notification settings - Fork 346
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
cargo: emit less debug info, and compile all deps in optimized mode #3447
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm conservative about changing the default build profile, but I'm not against this change if people like it.
Regarding debug = "line-tables-only"
, I don't think disk size is so important. The target directory will grow indefinitely anyway. If it breaks gdb, I would vote against it.
Since dependencies rarely change, I would prefer to compile all dependencies in optimized mode and compile only the crates in the repo in debug mode. What do you think? Is that possible/easy to configure? |
fwiw, I tried something like that for "pest", but it didn't help much. That's probably because the parsing code is generated by proc macro. |
Yes, that's exactly what the first change will do. The semantics are a bit weird but make sense; |
Yes, but anything to help fight off the nearly infinite disk space usage is nice IMO. Something is much better than nothing. :) Also, writing significantly less debug info does help compile times, though the Frankly I would be much happier if Cargo could actually GC the target directory as a first-class feature, but that's a bit of a pipe dream, at least for now...
Do you often use GDB for debugging? I admit, I nearly never use it for type-safe languages like Rust, but I guess that's maybe just because of my history in other compiled languages where I didn't need them or have DWARF symbols, so I was just stuck with fresh assembly code. Anything unsafe I just isolate and bang on and fuzz endlessly, manually. That's a bit "Back in my day I walked uphill both ways to get to school" though, so I get that it's not a great argument. TBH, I've wanted to have specific settings of mine put in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's exactly what the first change will do.
Heh, I somehow missed that. Sorry.
insta.opt-level = 3 | ||
similar.opt-level = 3 | ||
[profile.dev.package."*"] | ||
codegen-units = 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is what makes it so much slower. I agree with Yuya that the size of the binary is not important to optimize for.
I'll happily approve a PR that just sets opt-level = 3
for all dependencies and nothing else (but it's a significant change, so you might want to wait to hear from others too).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, codegen-units=1
has nearly no impact at all on compile times (or at least the fluxuations are minor), and also has almost no (repeatably measurable) impact on runtime for me, either. I included it for a more pedestrian reason: so that the dependencies in the development build more closely match the dependencies in the release build, where we do set that option. But I can drop it too, if we'd like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And also, I want to be clear it is not the size of the final binaries that I am worried about with the line-tables-only
change. It is the size of every intermediate artifact ever compiled — by rust-analyzer, by running nextest, from dependabot updates, etc. My development machine for jj
has 1TB of space, but it's absurd that Cargo can eat almost +100GiB every two weeks for a single project. This will continue to get worse as we pile in more crates (but that's another discussion). I think that just building once in release profile and once in the dev profile will put you at 10GB of disk space usage... It piles up very fast.
There are other factors here, for example my machine uses mold for linking, but I suspect that this change would have a positive impact on non-mold users (where there is no parallelism, and debuginfo tends to have a disproportionate affect on link time). I also suspect that on an actual HDD where write times are 100x slower and random reads are slow and sequential will probably see improvements, too. But those are just speculation; I haven't tested them, though I'm happy to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On my machine, codegen-units=1
on dev deps increases the build time from about 50s to about 60s. Since dependencies are rarely recompiled, I'm fine with either.
I'm fine with this, even if normal builds take a bit longer. The linetables change is nice for development but makes it harder to diagnose issues for users, so let's hope our dependencies don't break to much 🙏 . |
Not often, but I occasionally do. Last time I used gdb was to debug libgit2 behavior. If I were new to jj codebase, and debugger didn't work, I would be confused. |
+1 for the notion that it would be nice if debuggers still worked after this change. For what it's worth though, I'd also be fine if we just added a doc that discussed how to get the debugger working properly. It's not a simple as setting a breakpoint in an IDE since the tests run the CLI in a subprocess, so if the user also needs to build with a different profile that seems ok as long as it's documented with instructions. |
efc2afc
to
fd3d464
Compare
fd3d464
to
cc99b80
Compare
8e2e18e
to
40b1b26
Compare
40b1b26
to
1ee6f0b
Compare
Yuya noted the other day that `pest 2.7.9` seemed to cause testing slowdowns. Out of curiosity, I decided to see how much `opt-level=0`, which is implied by the default `dev` profile, costs us. This sets `opt-level=3`, and also sets `codegen-units=1` as well, which should improve output object file size and performance, too. This dramatically speeds up testing by approximately 33% (45 -> 30s on my machine.) However, it comes at the cost of a higher initial compile time for dependencies; clean rebuilds nearly double now, from about 40s -> 1m30s. This is probably a worthy tradeoff, though. This is all tested on my 6-core/12-thread AMD Zen 3 desktop. We could target more specific dependencies; we already do so with `insta`. But compiling everything helps ensure we don't hit more performance cliffs when some dependency introduces a codepath that behaves very poorly when unoptimized, especially when they incrementally add up over time and the frog slowly boils. We may want to tune Dependabot updates to be a little more spaced out (perhaps once a week, if we can do so) in order to compensate for this. Signed-off-by: Austin Seipp <[email protected]> Change-Id: I6d84fac2b9d64d6ef1c8187f227cd1c1caa195ab
This causes `rustc` to only emit enough debuginfo to emit backtraces with filepaths and line numbers, but nothing more. This has a massive impact on the size of `target/` in practice; a clean rebuild of all dependencies (tested via `cargo nextest run --workspace --no-run`) goes from ~5.5GiB to 2.1GiB. This should help us stave off the dreaded sacrificial "delete `target/` to save disk space" ritual that we occasionally must invoke (today I realized my `jj` build dir was over 120GiB.) Signed-off-by: Austin Seipp <[email protected]> Change-Id: Ia1f31b87da89e59d77f54a3d79cb45113db215dc
1ee6f0b
to
1e2d3ce
Compare
See commit messages for details.