-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Major regression in type checking performance compiling rustdoc #21694
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: