rust-lang / rust-lang/rust

Incremental compilation on Windows is slow because of hard links

Open
#137,560 5 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-incr-comp I-compiletime O-windows T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Every time I recompile my Rust project after a change it takes 2 or 3 seconds. I was wondering where that time is spent. I used the measureme/summarize tool to profile the rust compiler and it showed me that most time is spent in the codegen_copy_artifacts_from_incr_cache stage:

+--------------------------------------------------------+-----------+-----------------+----------+------------+-----------------------+---------------------------------+
| Item                                                   | Self time | % of total time | Time     | Item count | Incremental load time | Incremental result hashing time |
+--------------------------------------------------------+-----------+-----------------+----------+------------+-----------------------+---------------------------------+
| codegen_copy_artifacts_from_incr_cache                 | 12.24s    | 83.333          | 12.24s   | 255        | 0.00ns                | 0.00ns                          |
+--------------------------------------------------------+-----------+-----------------+----------+------------+-----------------------+---------------------------------+
| run_linker                                             | 448.51ms  | 3.054           | 448.51ms | 1          | 0.00ns                | 0.00ns                          |
+--------------------------------------------------------+-----------+-----------------+----------+------------+-----------------------+---------------------------------+
| incr_comp_prepare_session_directory                    | 416.99ms  | 2.840           | 416.99ms | 1          | 0.00ns                | 0.00ns                          |
+--------------------------------------------------------+-----------+-----------------+----------+------------+-----------------------+---------------------------------+
| LLVM_passes                                            | 414.15ms  | 2.820           | 414.15ms | 1          | 0.00ns                | 0.00ns                          |
+--------------------------------------------------------+-----------+-----------------+----------+------------+-----------------------+---------------------------------+
| copy_all_cgu_workproducts_to_incr_comp_cache_dir       | 349.22ms  | 2.378           | 349.22ms | 1          | 0.00ns                | 0.00ns                          |
+--------------------------------------------------------+-----------+-----------------+----------+------------+-----------------------+---------------------------------+
| codegen_crate                                          | 264.25ms  | 1.800           | 375.35ms | 1          | 0.00ns                | 0.00ns                          |
+--------------------------------------------------------+-----------+-----------------+----------+------------+-----------------------+---------------------------------+
...   

The reported time is larger than the actual time, probably because of multithreading.

This stage involves creating hard links.

Process Monitor shows that there are many SetLinkInformationFile syscalls some of which take 100-200ms each:

Image

I have observed this behaviour on many different projects.

Steps to reproduce in any Rust project of non-trivial size are:

  1. cargo build
  2. Make any small change, like changing a string literal.
  3. cargo rustc -- -Z self-profile
  4. summarize summarize <filename>.mm_profdata

Looks like creating hard links is sometimes very slow on Windows. Maybe some other strategy can be used to avoid creating so many hard links?


rustc 1.87.0-nightly (f8a913b13 2025-02-23)
binary: rustc
commit-hash: f8a913b1381e90379c7ca63ac2b88b9518936628
commit-date: 2025-02-23
host: x86_64-pc-windows-msvc
release: 1.87.0-nightly
LLVM version: 20.1.0

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in compiler/rustc_codegen_ssa/src/back/write.rs at the hard-link creation used by codegen_copy_artifacts_from_incr_cache. Reproduce on Windows with cargo build, a small source change, and cargo rustc -- -Z self-profile, then inspect the profile with summarize. Done means identifying and addressing the slow hard-link behavior without regressing incremental compilation, with profiling or timing evidence showing improvement.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
build-system, compilers, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.