-
Notifications
You must be signed in to change notification settings - Fork 892
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
Improve performance - skip manifest read if no components/targets requested #2917
base: master
Are you sure you want to change the base?
Conversation
It looks like the Is my understanding correct here? And is it reasonable to a command like |
Personally I think the request to show the active toolchain (which implies checking for components in the I remain convinced that the correct way to ameliorate the incredible slowness of parsing the TOML is to, instead, keep a cached faster-to-parse copy alongside it, e.g. BINCODE. |
Has any profiling been done on the TOML parsing itself? Just glancing through the file, the parsing code doesn't seem especially efficient, it could probably benefit from a little focused attention. edit: I just created one and the main thing that stands is tons and tons of individual allocations and drops |
I created a small one. use std::fs::read_to_string;
fn main() {
let s = read_to_string("/home/josh/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/multirust-channel-manifest.toml").unwrap();
for _ in 0..10 {
s.parse::<toml::Value>().unwrap();
}
} This runs in ~450ms on my machine. I found I can improve this by ~100ms by bypassing the
I'd like to poke around at this. How did you gather this data? |
If you pass the |
I've been using frida tracing to count malloc calls, and its about 100,000 allocations to parse the manifest file a single time (so the example above would be 10x that). I replaced I'm probably not going to continue down this path right now, but I'd be very curious to see if anyone else comes up with anything fruitful here. |
I was looking into why rustup had a performance penalty over calling cargo directly in simple cases, and found most of the time was spent parsing the
multirust-channel-manifest.toml
file. Looking more closely, it seemed parsing that file was not really required in many cases. This PR tweaks the ordering of the code to skip parsing this file when it isn't needed.I do not intend to make any behavioral change with this, other than potentially if some code paths handle an error while reading this file (and now they won't see that error in cases where we skip reading the file entirely). I believe this is the reason the
heal_damaged_toolchain
test is now failing. I need to look into this more closely (this PR is marked as draft until I figure this out), but I'd appreciate any insight into whether that test was intended to cover this behavior.The performance changes were tested in a brand new hello world cargo project (
cargo new hello
), after building rustup in release mode and installing it into arustup/home
directory as described in the contributing guidelines. The before tests were done on the current master branch, because it seems to already be much faster than the most recent official release.Before this change a repeated call to
cargo build
(through the rustup proxy) would take ~90ms. After this change it takes ~35ms. Running cargo directly takes ~22ms. So this change reduces the rustup overhead in this case from 68ms to 13ms (a reduction of 80%).