Flatten all -L search paths into a single list of files - #158823
Conversation
|
r? @mati865 rustbot has assigned @mati865. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
Sorry, meant to open this as a draft, but missclicked. r? @ghost |
This comment has been minimized.
This comment has been minimized.
|
This generally makes sense to me.
Was this considered by cargo team when the new build dir layout was designed? Why wasn't it considered an issue? |
|
I'm sure that it was considered, though I don't know if there were any alternatives. CC @ranger-ross @epage if you have more context. Recently we identified some optimizations that can be made to reduce that effect, they are being landed now (rust-lang/cargo#17168). |
|
Splitting rlibs into unique directories is fairly fundamental to the design. The trivial solution from there is hundreds of |
|
I thought about the mega-symlink-dir approach too :) Might be interesting to try, as that might also have some performance implications. I hope that with rust-lang/cargo#17168 and this PR landing and rust-lang/cargo#17183 being resolved, it will become workable, but we'll have to see how the new build dir layout works in practice to find out. |
8bba6cb to
0e1ba38
Compare
|
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Flatten all -L search paths into a single list of files
|
@bors try parent=45bc0d28cc57296e36ef653a442e96367ba73d4a |
This comment has been minimized.
This comment has been minimized.
Flatten all -L search paths into a single list of files
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Finished benchmarking commit (a31f58e): comparison URL. Overall result: ✅ improvements - no action neededBenchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf. @bors rollup=never rustc-perf Instruction countOur most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.
Max RSS (memory usage)Results (primary -0.9%, secondary -0.8%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (primary -1.0%, secondary -2.3%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeThis perf run didn't have relevant results for this metric. Bootstrap: 488.239s -> 487.438s (-0.16%) |
This comment has been minimized.
This comment has been minimized.
2702de0 to
2381c84
Compare
|
Thanks, applied the suggested changes. @rustbot ready |
|
r=me after addressing #158823 (comment) and squashing commits. |
b2dd117 to
55500ae
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
|
@bors r+ |
This comment has been minimized.
This comment has been minimized.
What is this?This is an experimental post-merge analysis report that shows differences in test outcomes between the merged PR and its parent PR.Comparing ad3d0bc (parent) -> 6c04025 (this PR) Test differencesShow 1 test diffStage 2
Job group index
Test dashboardRun cargo run --manifest-path src/ci/citool/Cargo.toml -- \
test-dashboard 6c04025a8a1d2b4b25283bb56b6c6450e3d38ba7 --output-dir test-dashboardAnd then open Job duration changes
How to interpret the job duration changes?Job durations can vary a lot, based on the actual runner instance |
|
Finished benchmarking commit (6c04025): comparison URL. Overall result: ❌✅ regressions and improvements - please read:Our benchmarks found a performance regression caused by this PR. Next Steps:
@rustbot label: +perf-regression Instruction countOur most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.
Max RSS (memory usage)Results (primary -1.2%, secondary -0.4%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (primary -0.4%, secondary -7.5%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeThis perf run didn't have relevant results for this metric. Bootstrap: 495.641s -> 491.569s (-0.82%) |
View all comments
This is an optimization that mostly targets the new Cargo build dir layout.
Before, Cargo usually used to pass rustc a single
-Lpath to a directory containing potentially a large number of.rlibor other dependency paths. Rustc is optimized for this, and does a preprocessing step, where it preloads all files from this directory into a sorted vector, in which it then performs binary search to look for files having a given prefix and postfix.With the new build dir layout, this changes, and Cargo will pass potentially many (even hundreds, if your crate has many dependencies)
-Ldirectories, where each directory will usually have only 1-2 files. This is not ideal for the current rustc search implementation, because the old preprocessing isn't really worth it when the-Ldirectory typically only has a single file, and because rustc will do a lot of work per each-Ldirectory in the lookup phase, including some quadratic (O(n^2)) work.With the
large-workspacestress test from rustc-perf, where the final binary has ~1000 total and ~500 direct dependencies:FilesIndex::query1938314calls toFilesIndex::query. Not ideal :)This PR modifies the logic so that instead of going through all
-Ldirectories one by one when we are looking for a specific dependency, we pre-gather all files from all passed-Ldirectories at the start, and sort them all together. Then, in the lookup phase, instead of performing <number of -L dirs> * 4 (.rmeta, .rlib, etc.) searched, we only perform the 4 searches across all files. This gets rid of the O(n^2) behavior.Further improvements could be made, e.g. sort the files just once and then filter it for for both host and target filesearchs. I alsothought about pre-filtering the files further, e.g. based on their
kind, but that is not worth it in usual situations, where ~all of the deps will be.rlibs or.rmetas anyway. What might work is pre-filtering based on their actual names (we strip known prefixes from them and then search based on the names alone, in a hashmap or something?), but that can be a follow-up.Diff vs parent. of #159857: https://perf.rust-lang.org/compare.html?start=1a833e16546c2eb012758ddd499964fd8afee29e&end=6514e2707b7e90fecbc570eeaa36f3780a9b02b4&stat=instructions%3Au