-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Avoid adding duplicate relations during inference #32042
Conversation
This reduces the amount of redundant equivalence checks for programs which use associated types in combination with deeply nested types. As an example this brings down the compilation times of tests in `combine` from 9m32s to 6m44s.
r? @nikomatsakis (I think @arielb1 is busy ...) |
I tried this PR on some test cases from the Parsell library, and saw no noticeable change. The test case I've been using from the standard library is just: fn main() {
let iter = (1..2)
.chain(1..2)
.chain(1..2)
.chain(1..2)
.chain(1..2)
.chain(1..2)
.chain(1..2)
.chain(1..2)
.chain(1..2)
.chain(1..2)
.chain(1..2)
.chain(1..2);
for x in iter { println!("{:?}", x); }
} which takes about 7s to type-check on both nightly and on the PR. It's altogether likely that I've messed up somewhere, this is my first time compiling rustc from a PR. Do you have a simple example that demonstrates the expected speedup? |
@asajeffrey I have not been able to extract a simple test case unfortunately so I have only tested it by building the tests in combine. (I ran cargo test --features test --verbose and then ran the command that was emitted). When you tested using parsell, did you test the version with or without the workaround you mentioned in #22204? |
If it helps, look at #21231 for the specific behavior which I try to reign in. From what I can tell, what happens during unification is that a lot of variables gets inferred to be equal relative each other before they are actually assigned a concrete type. I.e This.causes n! relations be generated and the slowdown comes naturally. I tried to remedy this by avoiding to add duplicated relations as well as avoiding to add already resolved relations back onto the stack. Normally something like a disjoint-set would be used make reduce this large number of created relations but subtyping unfortunately prohibits this. |
It would be helpful to have a small isolated test illustrating the behavior that you are modifying. |
@Marwes I ran it on the current version of parsell, which has lots of work-arounds to try to keep type-checking time down to minutes. |
Ok, this took far longer than I expected it to but I made a different solution to the same problem which can be found at #32062. @nikomatsakis I added a minimal example to #32062 which shows the problem. Please take a look at that PR instead as it should be far superior (combine typechecks in 12s rather than 500s in the current nightly and 350s in this PR). @asajeffrey This (and the new PR) only fixes the compile times of the use of associated types so I don't find it surprising that it does not improve parsell's compile times (as of yet, I have a theory which may fix the compile times for your iterator chaining example as well). |
Closing in favor of #32062 |
This reduces the amount of redundant equivalence checks for programs
which use associated types in combination with deeply nested types.
As an example this brings down the compilation times of tests in
combine
from 9m32s to 6m44s.Link to combine