-
Notifications
You must be signed in to change notification settings - Fork 462
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: rewrite UnusedVariables lint #3186
Conversation
!bench |
Mathlib CI status (docs):
|
The new warnings produced in Std and Mathlib are false positives, e.g.
is not unused. |
I'm going to try to extract some of those as additional test cases, since the lean4 test suite passed. |
@[inline] def compareOn [ord : Ord β] (f : α → β) (x y : α) : Ordering :=
compare (f x) (f y) Are you sure? It looks pretty unused to me. Is there an It looks like a bug in the original code relating to autoImplicits, since @[inline] def compareOn {α β} [ord : Ord β] (f : α → β) (x y : α) : Ordering :=
compare (f x) (f y) does trigger the unused variables warning on |
I reviewed all of the new linter warnings, and all of them appear to be correct (to spec; I know some people have doubts about this algorithm but it's doing what it is designed to do). Do I need to make a fix PR before it is possible to !bench this? |
Mathlib's I'm not sure why the bot didn't respond to your |
!bench |
Here are the benchmark results for commit c7f6b42. Benchmark Metric Change
===========================================
- stdlib type checking 2.3% (11.1 σ) |
I'm pretty sure it's because I don't have permission to run the bot (the list of approved users is separate from org members, and I think only you and Sebastian and Leo can run it, and possibly other FRO members as well). |
Note that two tests in the Lean 4 test suite accidentally test false positives. See the |
leanprover-community/mathlib4#9803, are you saying that I should run |
One part of the algorithm is supposed to address this: If there is a global constant info over the same span as a variable declaration, then it is not linted. Apparently this only works for (mutual) |
If you want to run the mathlib benchmark, you have to say |
The adjusted implementation of |
Turns out the reason for the issue is because it is being explicitly excluded. I pushed a fix, but given that this was deliberate behavior I guess @Kha and @mhuisi should work out whether it is better to lint on unused |
Do you already have numbers on specific, big proofs? E.g. I believe a few theorems in https://github.com/cedar-policy/cedar-spec/blob/main/cedar-lean/Cedar/Thm/Validation/Typechecker/LUB.lean took a significant time in the linter, would be great to have a comparison. I'm mostly wondering whether this change reduces the issue to a non-issue for them or whether it will pop up again for proofs twice as big. |
I don't, but there are asymptotic improvements in this PR, the metavariable scanning was reduced from O(n^2) to O(n) and I believe that's the main bottleneck so I would expect it to have outsized impact on the big proofs that reportedly had issues with this linter. I just pulled the cedar repo (217b74e) and the LUB file was noticeably slow to compile, but with |
I added a bunch of docs, I think this is ready for review. I still need to double check that all the builtin ignore fns are documented correctly and all do something - I think some of them are currently useless. |
Is that something that is affected by this PR, or should that wait for another PR? |
Well only insofar as the docs were just added and it would be good to make sure they are correct |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Tests need a copy-produced
Is this auto-corrupt kicking in? I can't make sense of it. |
copy-produced is described here: https://lean-lang.org/lean4/doc/dev/testing.html#fixing-tests |
This is a rewrite of the `UnusedVariables` lint to inline and simplify many of the dependent functions to try to improve the performance of this lint, which quite often shows up in perf reports. * The mvar assignment scanning is one of the most expensive parts of the process, so we do two things to improve this: * Lazily perform the scan only if we need it * Use an object-pointer hashmap to ensure that we don't have quadratic behavior when there are many mvar assignments with slight differences. * The dependency on `Lean.Server` is removed, meaning we don't need to do the LSP conversion stuff anymore. The main logic of reference finding is inlined. * We take `fvarAliases` into account, and union together fvars which are aliases of a base fvar. (It would be great if we had `UnionFind` here.) More docs will be added once we confirm an actual perf improvement. --------- Co-authored-by: Sebastian Ullrich <[email protected]>
@@ -398,7 +398,7 @@ def buildInductionCase (fn : Expr) (oldIH newIH : FVarId) (toClear toPreserve : | |||
mvarId ← assertIHs IHs mvarId | |||
for fvarId in toClear do | |||
mvarId ← mvarId.clear fvarId | |||
mvarId ← mvarId.cleanup (toPreserve := toPreserve) | |||
_ ← mvarId.cleanup (toPreserve := toPreserve) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nomeata This looks like an actual bug, you're never making use of this mvar?
This is a rewrite of the
UnusedVariables
lint to inline and simplify many of the dependent functions to try to improve the performance of this lint, which quite often shows up in perf reports.Lean.Server
is removed, meaning we don't need to do the LSP conversion stuff anymore. The main logic of reference finding is inlined.fvarAliases
into account, and union together fvars which are aliases of a base fvar. (It would be great if we hadUnionFind
here.)More docs will be added once we confirm an actual perf improvement.