Skip to content
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

Closed
tomjakubowski opened this issue Jan 27, 2015 · 13 comments
Closed

Major regression in type checking performance compiling rustdoc #21694

tomjakubowski opened this issue Jan 27, 2015 · 13 comments
Labels
P-medium Medium priority
Milestone

Comments

@tomjakubowski
Copy link
Contributor

A partial log of RUSTFLAGS="-Z time-passes" make x86_64-unknown-linux-gnu/stage2/bin/rustdoc, after doing a fresh rebuild on d77f6d5366b330f9c2061cad0d3ff638c9cc05b7:

time: 0.024     parsing
time: 0.000     recursion limit
time: 0.000     gated macro checking
time: 0.007     configuration 1
time: 0.000     crate injection
time: 0.003     plugin loading
time: 0.000     plugin registration
time: 0.181     expansion
time: 0.006     complete gated feature checking
time: 0.023     configuration 2
time: 0.023     maybe building test harness
time: 0.022     prelude injection
time: 0.003     checking that all macro invocations are gone
time: 0.028     assigning node ids and indexing ast
time: 0.035     external crate/lib resolution
time: 0.006     language item collection
time: 0.128     resolution
time: 0.004     lifetime resolution
time: 0.000     looking for entry point
time: 0.003     looking for plugin registrar
time: 0.017     region resolution
time: 0.003     loop checking
time: 0.000     stability index
time: 0.003     static item recursion checking
time: 0.021     type collecting
time: 0.007     variance inference
time: 0.321     coherence checking
time: 247.499   type checking
time: 0.077     check static items
time: 0.013     const marking
time: 0.003     const checking
time: 0.034     privacy checking
time: 0.008     intrinsic checking
time: 0.007     effect checking
time: 0.155     match checking
time: 0.020     liveness checking
time: 3.802     borrow checking
time: 2.099     rvalue checking
time: 0.003     reachability checking
time: 0.022     death checking
time: 0.173     lint checking
time: 0.000     resolving dependency formats
time: 13.342    translation

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.

@nikomatsakis
Copy link
Contributor

Nominating. We should track this down. Quite possibly due to #20304

@nrc
Copy link
Member

nrc commented Jan 27, 2015

cc me

@nrc
Copy link
Member

nrc commented Jan 29, 2015

I've been profiling this and the most time was spent in the hash function for Substs. Which is kind of weird.

@nikomatsakis
Copy link
Contributor

interesting, could be related to @huonw's changes to intern Substs

@pnkfelix
Copy link
Member

Polish issue, but worth trying to address by 1.0 beta.

@pnkfelix pnkfelix added this to the 1.0 beta milestone Jan 29, 2015
@pnkfelix pnkfelix added P-medium Medium priority and removed I-nominated labels Jan 29, 2015
@nikomatsakis
Copy link
Contributor

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

@jdm
Copy link
Contributor

jdm commented Jan 30, 2015

cc me

@nrc
Copy link
Member

nrc commented Jan 30, 2015

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 - SelectionContext::evalute_predicate_recursively is the overarching method in the profile. Winnowing in particular is taking ~75% of the time.

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.

@sanxiyn
Copy link
Member

sanxiyn commented Feb 2, 2015

FYI, slowness is caused by trying to infer and check an excessive use of iterator chain.

@nikomatsakis
Copy link
Contributor

Interesting. That fits with @nick29581's profiles, for sure.

@nikomatsakis
Copy link
Contributor

we should make a standalone test case...

@huonw
Copy link
Member

huonw commented Feb 2, 2015

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(())
        ;
}
$ rustc slow-typeck.rs -Z time-passes --cfg equality | grep 'type checking'
time: 0.219     type checking
$ rustc slow-typeck.rs -Z time-passes | grep 'type checking'
time: 0.014     type checking

(The blow-up appears to be exponential.)

bors added a commit that referenced this issue Feb 2, 2015
This avoids triggering #21694. It probably is a better way to do it anyway.
@nrc
Copy link
Member

nrc commented Feb 12, 2015

Closing this - the rustdoc-specific perf issue has been fixed in #21864. I have opened #22204 for the general case.

@nrc nrc closed this as completed Feb 12, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P-medium Medium priority
Projects
None yet
Development

No branches or pull requests

7 participants