-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Perf regression in nightly when compiling massive matches #29227
Comments
cc @rust-lang/compiler, seems like some low hanging fruit perhaps? |
Perhaps, yeah. Thanks for the report! |
Well, it probably requires tweaking MIR somewhat to have a more general "switch" style statement, as @Aatch suggested at some point. |
@nikomatsakis I believe I've seen MIR building turn constant patterns not into plain |
@eddyb ah yes, I meant to writeup an RFC on this point. I believe the
and
should always be equivalent, if both of them compile. (I could imagine On Fri, Oct 23, 2015 at 3:21 AM, Eduard-Mihai Burtescu <
|
I don't think there's a way to change that and not break backwards compat, as currently the purity of OTOH, expanding associated constants may require delaying match MIR generation post-monomorphization, at least for the associated constant pattern, not necessarily the whole |
@eddyb I consider the current behavior a bug, that it is accepting more
code than it ought to. But I would want to evaluate the impact of any
change, to be sure. Note: I also don't consider purity in matches to be a
requirement. After all, I'd like to permit `box` patterns, which do a
deref. That is also note pure.
We simply cannot expand associated constants, I don't think. I mean
technically yes we could wait till after monomorphization, but we'd also
have to avoid doing the exhaustiveness checks until that point as well,
since they are influenced by the constant-to-pattern expansion.
|
I am not sure we want to support non-resolvable associated constants in |
@nikomatsakis Exhaustivity-wise, we can just be conservative, which might indeed be too much of a restriction for associated constants to be useful at all in matches. As for the Actually, scratch that, it was for a different feature ( |
This is pretty off topic for this issue. I plan to open a discussion thread On Sat, Oct 24, 2015 at 3:50 AM, Eduard-Mihai Burtescu <
|
This was accidentally closed. The issue is not solved, though #29384 is a temporary workaround to prevent regressing the stable release. |
(I did start a branch that I THINK will resolve this issue, however.) |
Introduce a `SwitchInt` and restructure pattern matching to collect integers and characters into one master switch. This is aimed at #29227, but is not a complete fix. Whereas before we generated an if-else-if chain and, at least on my machine, just failed to compile, we now spend ~9sec compiling `rustc_abuse`. AFAICT this is basically just due to a need for more micro-optimization of the matching process: perf shows a fair amount of time just spent iterating over the candidate list. Still, it seemed worth opening a PR with this step alone, since it's a big step forward.
The older algorithm was pretty inefficient for big matches. Fixes #29227. (On my computer, MIR construction on this test case goes from 9.9s to 0.025s.) Whereas before we had a loop like: - for all outcomes of the test we are performing - for all candidates - check whether candidate is relevant to outcome We now do: - for all candidates - determine which outcomes the candidate is relevant to Since the number of outcomes in this case is proportional to the number of candidates, the original algorithm turned out to be O(n^2), and the newer one is just O(n). This PR also does some minor speedups by eagerly mirroring all patterns, so that we can just pass around `&Pattern<'tcx>`, which makes cloning cheaper. We could probably go a bit further in this direction. r? @Aatch
The file located here: https://gist.github.com/swgillespie/37b32f7b09ae536df8dc when compiled using
rustc rustc_abuse.rs -o rustc_abuse -Z time-passes
takes approximately 9 seconds and 40MB of memory to compile on stable and beta, while taking almost a minute and 4GB of memory on nightly.The Bad Thing being done here is that there are several massive matches. As expected, match checking takes a few seconds, but the real culprit here seems to be "MIR dump", which is where the memory usage peaks. The memory usage is high enough to get my Travis CI build killed that has some code similar to this, but not as extreme.
These numbers were gathered with:
rustc 1.5.0-nightly (4826f9625 2015-10-21)
rustc 1.4.0-beta.3 (20eba406f 2015-10-16)
rustc 1.3.0 (9a92aaf19 2015-09-15)
.The text was updated successfully, but these errors were encountered: