-
Notifications
You must be signed in to change notification settings - Fork 367
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
[Merged by Bors] - perf: eagerly elaborate leaf nodes in linear_combination
#15599
Conversation
Previously, `expandLinearCombo` would throw away the terms it would elaborate when determining which ones were proofs. Now, it saves these subproblems. This brings the elaboration of a complicated example from 3.91s to 1.85s. We further bring this down to 0.286s by controling the elaboration of `^`, forcing the exponent to fully elaborate, which lets the HPow instances specialize more quickly. This is OK since we do not expect core Lean's HomogeneousPow instances to be applicable in the usual applications of `linear_combination`. This is similar to PR #15570, but it uses the standard expression elaborator. Co-authored-by: Heather Macbeth <[email protected]>
PR summary 69100ddaf9Import changes for modified filesNo significant changes to the import graph Import changes for all files
Declarations diff
You can run this locally as follows## summary with just the declaration names:
./scripts/declarations_diff.sh <optional_commit>
## more verbose report:
./scripts/declarations_diff.sh long <optional_commit> The doc-module for |
linear_combination
^
elaboration for linear_combination
This speedup is confusing to me, because, if I understand correctly, it's not just about the |
@hrmacbeth I think the deal is that in your branch in the exponentiation case, it's only committing to the fully-elaborated exponent if the base of the exponent is a proof. Mine commits even if the base isn't a proof. To spell out my understanding of the problem a bit more, when you have With my version of the code, we fully elaborate |
Thanks, that's instructive. So here's another version to consider: don't special-case exponentiation, just pre-elaborate every leaf term (noting that we know the expected type, because we can take it from the goal). This is a little slower, 8,374 rather than 7,763 heartbeats, but not by much. And perhaps it might also avoid similar problems in situations other than exponentiation? |
^
elaboration for linear_combination
linear_combination
@hrmacbeth Good idea. I've updated the PR, and managed to re-use the elaboration in leaf nodes to bring down the heartbeats further. Let's see if mathlib builds! |
By the way, in the long term I'm not in favour of the "exponentiation" capability this PR adds (like Short version of my rationale: the I'm happy for this PR to be merged as-is ... I can open another PR later to allow that discussion to happen separately. |
Co-authored-by: Heather Macbeth <[email protected]>
@hrmacbeth This is so close to just generating expressions instead of going through macros, so I implemented a version that calls elaboration functions directly to do this, and for the big example it just saves 300 heartbeats, without measurably taking any less time. It adds a lot of complexity for no reason, so I'm not pushing it. I think this proves that the fundamental slowdown is really just from instance synthesis and bounding the elaboration problems rather than using a macro-based approach. I benchmarked your Qq version too, and it takes 0.29s on my computer, with 7500 heartbeats. What do you think? Should we go with this version? Or go with the Qq one, and hopefully fix how it elaborates expressions so that you don't need to change any of mathlib? |
@kmill This has been a very interesting exploration for me to follow, but I don't feel equipped to judge between the two implementations we have reached: the crude metric of speed is the only one I know for judging meta code, and they seem to be the same on this. So, your call -- do you think one version has an edge over the other in simplicity or in maintainability? |
@hrmacbeth I think that this non-Qq version might be easier to maintain, and it has the bonus of being a drop-in replacement. I still don't completely feel like I have a complete handle on the issue... but I think we've pretty well localized it to elaborating large arithmetic expressions being slow, and the |
Sounds good to me! You made me a co-author on this, so I won't merge directly :) maintainer merge |
🚀 Pull request has been placed on the maintainer queue by hrmacbeth. |
bors merge |
Since the arithmetic type is known from the equality goal, we can eagerly elaborate all leaf nodes in `expandLinearCombo` while also avoiding re-elaborating them when deciding whether they are proofs or not. This brings the elaboration of a complicated example (see tests) from 3.91s to 0.29s. The main issue is that large expressions can be slow to elaborate. In particular, exponentiation relies on the default instance mechanism, which appears can take quadratic time to resolve. Forcing the resolution of default instances within each coefficient of the linear combination bounds the default instance problems. This is similar to PR #15570, but it sticks with the syntax transformation paradigm. Co-authored-by: Heather Macbeth <[email protected]>
Pull request successfully merged into master. Build succeeded: |
linear_combination
linear_combination
Since the arithmetic type is known from the equality goal, we can eagerly elaborate all leaf nodes in `expandLinearCombo` while also avoiding re-elaborating them when deciding whether they are proofs or not. This brings the elaboration of a complicated example (see tests) from 3.91s to 0.29s. The main issue is that large expressions can be slow to elaborate. In particular, exponentiation relies on the default instance mechanism, which appears can take quadratic time to resolve. Forcing the resolution of default instances within each coefficient of the linear combination bounds the default instance problems. This is similar to PR #15570, but it sticks with the syntax transformation paradigm. Co-authored-by: Heather Macbeth <[email protected]>
Since the arithmetic type is known from the equality goal, we can eagerly elaborate all leaf nodes in `expandLinearCombo` while also avoiding re-elaborating them when deciding whether they are proofs or not. This brings the elaboration of a complicated example (see tests) from 3.91s to 0.29s. The main issue is that large expressions can be slow to elaborate. In particular, exponentiation relies on the default instance mechanism, which appears can take quadratic time to resolve. Forcing the resolution of default instances within each coefficient of the linear combination bounds the default instance problems. This is similar to PR #15570, but it sticks with the syntax transformation paradigm. Co-authored-by: Heather Macbeth <[email protected]>
Since the arithmetic type is known from the equality goal, we can eagerly elaborate all leaf nodes in `expandLinearCombo` while also avoiding re-elaborating them when deciding whether they are proofs or not. This brings the elaboration of a complicated example (see tests) from 3.91s to 0.29s. The main issue is that large expressions can be slow to elaborate. In particular, exponentiation relies on the default instance mechanism, which appears can take quadratic time to resolve. Forcing the resolution of default instances within each coefficient of the linear combination bounds the default instance problems. This is similar to PR #15570, but it sticks with the syntax transformation paradigm. Co-authored-by: Heather Macbeth <[email protected]>
Since the arithmetic type is known from the equality goal, we can eagerly elaborate all leaf nodes in
expandLinearCombo
while also avoiding re-elaborating them when deciding whether they are proofs or not. This brings the elaboration of a complicated example (see tests) from 3.91s to 0.29s.The main issue is that large expressions can be slow to elaborate. In particular, exponentiation relies on the default instance mechanism, which appears can take quadratic time to resolve. Forcing the resolution of default instances within each coefficient of the linear combination bounds the default instance problems.
This is similar to PR #15570, but it sticks with the syntax transformation paradigm.
Co-authored-by: Heather Macbeth [email protected]