$ cargo rustdoc --features=stm32h742 -- -Z time-passes
time: 45.092; rss: 2537MB collect-intra-doc-links
Finished dev [unoptimized + debuginfo] target(s) in 1m 59s
rustdoc --version:
rustdoc 1.49.0-nightly (ffa2e7ae8 2020-10-24)
cc https://github.com/stm32-rs/stm32-rs/issues/3
-Z self-profile
| Item | Self time | % of total time | Time | Item count |
+-------------------------------------------------+-----------+-----------------+----------+------------+
| collect-intra-doc-links | 45.67s | 52.971 | 45.68s | 1 |
+-------------------------------------------------+-----------+-----------------+----------+------------+
| render_html | 17.25s | 20.008 | 17.25s | 1 |
+-------------------------------------------------+-----------+-----------------+----------+------------+
| collect-trait-impls | 12.71s | 14.740 | 17.87s | 1 |
+-------------------------------------------------+-----------+-----------------+----------+------------+
| <unknown> | 5.36s | 6.221 | 7.20s | 2122524 |
+-------------------------------------------------+-----------+-----------------+----------+------------+
| clean_crate | 1.61s | 1.873 | 2.21s | 1 |
+-------------------------------------------------+-----------+-----------------+----------+------------+
Total cpu time: 86.209807708s
Nearly 100% of that time is spent in get_blanket_impls.

Is this even required for intra-doc links? AFAIK this is only for Send and Sync, which don't have associated items.
... why is InferCtxtInner::new taking a quarter of the time?
I think this could be sped up quite a bit by only considering traits that have an associated item of the right name. Then rustdoc wouldn't have to go through the trait system at all, just look at it long enough to see it wouldn't work even if it did apply to the type.
Relevant code: https://github.com/rust-lang/rust/blob/b385598c9658fef4a143a770c21db38b7872c134/src/librustdoc/passes/collect_intra_doc_links.rs#L605
https://github.com/rust-lang/rust/blob/b385598c9658fef4a143a770c21db38b7872c134/src/librustdoc/clean/blanket_impl.rs#L23
We could change get_blanket_impls to take a filter parameter, that wouldn't be too invasive I think.
It probably also doesn't help that for_each_relevant_impl simplifies the type to an extent where all generic args are erased and then iterates on all trait implementations of it:
If you have gazillions of impl Trait for F<A1> {} .... impl Trait for F<A10000> then that's a problem :)
Reducing the number of traits this (rather expensive) search is done is a good idea!
I think the strategy similar to https://github.com/rust-lang/rust/pull/78317#issuecomment-716294026 would be helpful here too, but I guess the lower hanging fruit (checking whether the trait contains the name in the first place) should be tried before.
Discussed in Discord with @jyn514 , I'll be trying my hand at this one :rocket:
@rustbot claim
Most helpful comment
Discussed in Discord with @jyn514 , I'll be trying my hand at this one :rocket:
@rustbot claim