-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Major regression in type checking performance compiling rustdoc #21694
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
Nominating. We should track this down. Quite possibly due to #20304 |
cc me |
I've been profiling this and the most time was spent in the hash function for |
interesting, could be related to @huonw's changes to intern |
Polish issue, but worth trying to address by 1.0 beta. |
but it's always possible that it's just that we're doing a lot more hashing -- i.e., it's the caller's problem |
cc me |
I did a bunch more profiling. First off, normalisation and projection barely showed up in the profile, so I think #20304 is a red herring. Substs interning did, but because it was called a huge number of times, it's not that expensive for each call. I tried disabling interning, for rustdoc this led to OOMs. For libcore which also has a very high type checking time (relative to other phases) this only reduced type checking time by 6%, so I predict it won't be helpful in the rustdoc case. The majority of the time is coming from trait selection - So, I don't think caching normalisation and projection is worthwhile, at least here, it might be for other reasons. I need to look a bit closer at the code around selections. AIUI, only first phase is cached and I don't think winnowing is. I wonder if we could cache that too? I also want to check that caching is working as expected and we're not missing where we should hit. |
FYI, slowness is caused by trying to infer and check an excessive use of iterator chain. |
Interesting. That fits with @nick29581's profiles, for sure. |
we should make a standalone test case... |
It seems to be related to the equality constraint between the associated types: struct Pair<A, B>(A, B);
trait Foo: Sized {
type Item = ();
fn foo<B>(self, other: B) -> Pair<Self, B> {
Pair(self, other)
}
}
impl Foo for () {
type Item = ();
}
#[cfg(equality)]
impl<A: Foo, B: Foo<Item = A::Item>> Foo for Pair<A, B> {
type Item = A::Item;
}
#[cfg(not(equality))]
impl<A: Foo, B: Foo> Foo for Pair<A, B> {
type Item = A::Item;
}
fn main() {
().foo(())
.foo(())
.foo(())
.foo(())
.foo(())
.foo(())
.foo(())
.foo(())
.foo(())
;
}
(The blow-up appears to be exponential.) |
This avoids triggering #21694. It probably is a better way to do it anyway.
A partial log of
RUSTFLAGS="-Z time-passes" make x86_64-unknown-linux-gnu/stage2/bin/rustdoc
, after doing a fresh rebuild ond77f6d5366b330f9c2061cad0d3ff638c9cc05b7
:Unfortunately I don't have a log of the last time I built rustdoc ~2 weeks ago, but if I recall type checking took no more than 30 or 40 seconds.
The text was updated successfully, but these errors were encountered: