perf: cache elaboration of section variables across commands - #14595
perf: cache elaboration of section variables across commands#14595marcelolynch wants to merge 1 commit into
Conversation
03fd3bc to
dc65ebd
Compare
|
!bench mathlib |
|
Benchmark results for leanprover-community/mathlib4-nightly-testing@1bd09a6 against leanprover-community/mathlib4-nightly-testing@51fd0ce are in. There are significant results. @marcelolynch
Large changes (2✅)
Medium changes (11✅, 1🟥)
Small changes (62✅)
|
|
Reference manual CI status:
|
|
Mathlib CI status (docs):
|
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
dc65ebd to
c393a43
Compare
|
!bench mathlib |
|
Benchmark results for leanprover-community/mathlib4-nightly-testing@1bd09a6 against leanprover-community/mathlib4-nightly-testing@51fd0ce are in. (These commits have already been benchmarked in a previous command.) There are significant results. @marcelolynch
Large changes (2✅)
Medium changes (11✅, 1🟥)
Small changes (62✅)
|
|
!bench mathlib |
|
Benchmark results for leanprover-community/mathlib4-nightly-testing@1bd09a6 against leanprover-community/mathlib4-nightly-testing@51fd0ce are in. (These commits have already been benchmarked in a previous command.) There are significant results. @marcelolynch
Large changes (2✅)
Medium changes (11✅, 1🟥)
Small changes (62✅)
|
This PR caches the elaboration of section variables. Before this change,
runTermElabMre-elaborated the binders of everyvariablecommand in scope for each command. A binder type whose class takes instance-implicit arguments, for example[Module R M], runs type-class synthesis on each re-elaboration. In long Mathlib sections, this cost reaches 20–30% of the instructions of a module (see the analysis in the discussion of leanprover-community/mathlib4#42214, which removes dead binders for this reason; live binders pay the same cost).The cache stores the elaborated binders of the current scope as a closed telescope in the command state. A command reuses the telescope when two checks pass: the scope is the same object (pointer identity, so any scope change invalidates), and the instance table has the same revision (a new
Meta.Instances.revisioncounter). Reuse instantiates fresh level metavariables, so each command can still constrain the universes of the section variables independently. A block is not cached when its elaboration auto-binds implicit variables or universe names, leaves expression metavariables (variable (n : _)) or postponed universe constraints, or containssorry. The reuse path replays theuniverseConstraintsCheckpointand recursion-depth behavior of the elaboration path.One intentional behavior change: with the cache, a global declaration between two commands of a scope does not change how the identifiers in earlier
variablebinders resolve for later commands. Before, a mid-sectiondef Nat := Unitsilently changed the type of a section variable(x : Nat)for subsequent declarations of the scope. The cache freezes the meaning of a binder at its first elaboration in the scope. Set the new optionElab.cacheSectionVarstofalseto restore the old behavior;tests/elab/sectionVarsCache.leandocuments the invariants and this change.Validation: a differential run of all 3097 files in
tests/elabwith the option on and off converged to no behavioral differences. The remaining diffs are environmental (timings, backtrace addresses, random bytes, pointer values, task interleavings), one metavariable index in an error message (the test driver strips these), and the documented resolution change. The differential run also found the need for three of the guards above, which shows the method works. A microbenchmark (80 trivial theorems under 20 instance binders) drops from 0.17s to 0.08s, against a 0.07s floor without binders.This is a draft to run the Mathlib benchmarks through a
lean-pr-testingtoolchain and measure the real-world gain. Known limitation for review: commands that reuse the cache do not emit binder info nodes for the section variables, so go-to-definition on a section variable use inside such a command may degrade in the language server; this needs a decision on how to re-attach the info cheaply.🤖 Generated with Claude Code