My coworker who uses Windows is experiencing ultra-long compile times and I'm not sure why. On Linux and Mac, cargo check is almost instantaneous, but on their Windows machine check / build / build --release all seem to have insanely long wait times.
We've tried completely disabling Windows Defender, but that didn't change anything.
On Linux, after adding a newline to a file to get it to rebuild:
cargo build --release takes 1 minute
cargo build takes 21 seconds
cargo check takes 4 seconds
On Windows, with the equivalent newline:
cargo build --release takes 2 minutes and 29 seconds.
After doing a self profile and looking at summarize, it says the CPU time was 20 seconds. However, when we built the project using cargo build it says 2 minutes.
Does this mean something on the OS is blocking rustc's CPU time?
If so, I'm not sure how to find that since we've already disabled Defender.
That is very strange! The self-profile times are based on wall-clock timers so even if the process isn't getting time on the CPU, that should still be tracked somewhere in the profile. Since it isn't, it's possible that cargo is waiting on something before starting the rustc process. You might want to try the cargo -Z timings flag to see if cargo is waiting on something.
We disabled it via the UI. How can we check if it's still enabled via a group policy? I would have though if it were enforced by a policy Windows would just say "no you can't disable it".
If you have Pro or Enteprise version of windows you can use group policies to make sure real-time protection is disabled.
You can find policy here: Computer Configuration > Administrative Templates > Windows Components > Microsoft Defender Antivirus
There you can find policy Turn off Defender Antivirus
Enabling this policy will disable antivirus protection and prevents you from enabling it via UI.
Note that I heard complaint from my friend who updates windows that it stopped working, but it works as intended on my machine
Before running this or the cargo rustc self-profile command, does it matter if we built the project already? Not sure if we should delete ./target beforehand.
It can make a difference because of incremental compilation but I would recommend just trying to reproduce the scenario that you originally reported about adding a newline to a file.
Although, if you can cargo check and then cargo check again with no changes and still see the same slowness, that is a clue as well.
We disabled Windows Defender as @DoumanAsh suggested, but no change to compile times were seen.
When we are compiling, Antimalware Service Executable is using about 0.1% CPU, so it doesn't look like it's doing anything.
@wesleywiser Without removing ./target and just adding a newline and running cargo check it finished in 1 minute 50 seconds. Running cargo check again with no changes finishes in 0.54s.
@wesleywiser Looking at cargo build -Z timings output, we compared removing ./target to just adding a newline. When removing ./target it shows all the dependencies, but that part is pretty fast. The worst offenders are our own workspace crates, which take up almost all the time.
There are two workspace crates which are library dependencies of one binary. That last part of the timings graph shows 54 seconds for the first library, 54 seconds for the second library, and 18 seconds for the binary itself.
It looks to me like something is causing incremental compilation to think it needs to rebuild your entire project. There are 256 instances of codegen_module and by default, we try to create 256 compilation units per crate when in incremental mode which suggests incremental thinks every compilation unit is dirty.
Do you by chance have any build scripts in your workspace which aren't using the rerun-if commands?
Can you also do cargo rustc --profile check --manifest-path ./my-crate/Cargo.toml -- -Zself-profile to see what is causing cargo check to take so long?
Ok, those results seem much more reasonable. It sounds like then that the issue lies outside rustc but perhaps in cargo? I would try running this and see what the graphs cargo generates looks like
I think we just figured out the cause, but it's still weird since it only affects Windows. We use SQLx, and setting SQLX_OFFLINE=true on the machine in question fixes everything and compile times are back down to normal. If this isn't set, SQLx will typecheck our SQL queries against a live database. Setting it to true will use a file cache of the queries instead.
On Linux, we don't need to enable SQLX_OFFLINE to get fast compile times. cargo check on Linux takes about 3 seconds.
I'm going to look into this more Monday to figure out if this is some Windows related issue in general by testing on other Windows machines, or if it's just affecting the one we've been testing on. If there is something throttling the Postgres network requests then that would explain it.
So my only question now is - shouldn't those network request times be included in a timings profile?