Skip to content

perf: cache elaboration of section variables across commands - #14595

Closed
marcelolynch wants to merge 2 commits into
leanprover:masterfrom
marcelolynch:sectionvars-cache-pr
Closed

perf: cache elaboration of section variables across commands#14595
marcelolynch wants to merge 2 commits into
leanprover:masterfrom
marcelolynch:sectionvars-cache-pr

Conversation

@marcelolynch

@marcelolynch marcelolynch commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

This PR caches the elaboration of section variables. Before this change, runTermElabM elaborated the binders of every variable command in scope for each command. The elaboration of a binder type can run type-class synthesis, and every command of a section repeats that work. 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 holds the binders of the current scope as a closed telescope in the command state. A command reuses the telescope when the cache key agrees. The key holds the scope, the revision of the instance table and the revision of the default instance table, and Meta.Instances and Meta.DefaultInstances each get a revision counter for it. The key compares scopes by pointer identity, so any change of the scope gives a different key. Each reuse makes fresh level metavariables, so every command constrains the universes of the section variables on its own. The cache does not take a block when the elaboration auto-binds an implicit variable or a universe name, leaves a metavariable or a postponed universe constraint, or contains sorry. The reuse path repeats the universe checkpoint and the recursion depth of the elaboration path.

A reuse reopens the telescope, which makes new free variables. The language server finds the binder of a free variable through its info node, so runTermElabM adds a binder info node for each new free variable. It takes the binder syntax from Term.elabBindersEx and adds the nodes with Term.addLocalVarInfo. MutualDef uses the same pattern after it reopens the telescope of a declaration. Without the nodes, go-to-definition, document highlight and find-references stop working on the section variables.

A scope without section variables skips the cache, because it has nothing to reuse and the work of the cache costs more than the elaboration of the empty block. The cache also stores a negative outcome. A block whose elaboration a telescope cannot reproduce, for example a block that auto-binds a universe name with Type*, built and discarded a telescope for every command of the scope. The cache records the outcome once, and the later commands of the scope elaborate the binders without that work.

The cache is an approximation, not an exact replay. It tracks the changes of the environment that can change the result of the type-class synthesis in the binder types, and it does not track the other changes. A new instance or a new default instance therefore invalidates the cache. A declaration that shadows a name in a binder type does not invalidate it, and a change of reducibility does not either. The visible consequence is the resolution of identifiers: with the cache, a declaration between two commands of a scope does not change how the identifiers in the binder types of earlier variable commands resolve. Set the option Elab.cacheSectionVars to false for the old behavior.

This criterion needs a decision from the reviewers. No document states when the binder types of a variable command resolve, and the present behavior follows from the storage of the binders as syntax. The variable command discussion on Zulip lists the current behavior as a defect, because the variables "elaborate to different expressions in different declarations", and it proposes a cache as one remedy. The cache removes that difference for identifiers and keeps it for instances. A full freeze is the other coherent option: it drops both revision counters and is simpler and faster, but it also stops a later instance from reaching an earlier binder, which is more likely to affect real code.

Validation: a differential run of all 3097 files in tests/elab with 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. No test of the suite depends on the old resolution behavior. A !bench run of an earlier revision measured -0.34% of the instructions of the build, with -10.45% for Std.Data.DHashMap.Lemmas and similar gains for the other Std.Data lemma modules. The same run showed small regressions for modules without section variables, and the two paragraphs above remove that cost.

tests/elab/sectionVarsCache.lean documents the invariants and the resolution change. It also covers the type-class synthesis that finds a section-variable instance on the reuse path, the binder annotations that survive the telescope, the addition and the erasure of an instance, the invalidation by a default instance, the blocks that the cache does not take, and the temporary scope of a set_option ... in prefix. tests/server_interactive/sectionVarsCacheInfo.lean checks go-to-definition and document highlight on a section variable in a command that reuses the cache.

This is a draft to run the Mathlib benchmarks through a lean-pr-testing toolchain and measure the real-world gain.

🤖 Generated with Claude Code

@marcelolynch
marcelolynch force-pushed the sectionvars-cache-pr branch from 03fd3bc to dc65ebd Compare July 29, 2026 15:54
@marcelolynch

Copy link
Copy Markdown
Contributor Author

!bench mathlib

@leanprover-radar

leanprover-radar commented Jul 29, 2026

Copy link
Copy Markdown

Benchmark results for leanprover-community/mathlib4-nightly-testing@1bd09a6 against leanprover-community/mathlib4-nightly-testing@51fd0ce are in. There are significant results. @marcelolynch

  • build//instructions: -391.9G (-0.27%)

Large changes (2✅)

  • build/module/Mathlib.Algebra.Star.NonUnitalSubalgebra//instructions: -21.1G (-20.66%)
  • and 1 hidden

Medium changes (11✅, 1🟥)

  • build/module/Mathlib.Algebra.Algebra.Equiv//instructions: -3.8G (-9.72%)
  • build/module/Mathlib.Algebra.Lie.Basic//instructions: -4.7G (-9.75%)
  • build/module/Mathlib.Algebra.Lie.Submodule//instructions: -4.8G (-8.69%)
  • 🟥 build/module/Mathlib.AlgebraicTopology.SimplicialSet.NerveAdjunction//instructions: +19.6G (+20.83%)
  • build/module/Mathlib.Analysis.Calculus.ContDiff.Defs//instructions: -10.7G (-9.92%)
  • build/module/Mathlib.Analysis.Calculus.ContDiff.FTaylorSeries//instructions: -15.8G (-13.12%)
  • build/module/Mathlib.Analysis.Calculus.FormalMultilinearSeries//instructions: -7.4G (-17.84%)
  • build/module/Mathlib.Analysis.Convolution//instructions: -13.8G (-12.15%)
  • build/module/Mathlib.LinearAlgebra.TensorProduct.Tower//instructions: -22.3G (-15.83%)
  • build/module/Mathlib.RepresentationTheory.Continuous.TopRep//instructions: -4.3G (-9.78%)
  • build/module/Mathlib.SetTheory.Cardinal.Cofinality.Club//instructions: -5.4G (-18.63%)
  • build/module/Mathlib.Topology.MetricSpace.IsometricSMul//instructions: -2.5G (-9.47%)

Small changes (62✅)

  • build/module/Mathlib.Algebra.Algebra.Hom//instructions: -1.3G (-6.64%)
  • build/module/Mathlib.Algebra.Algebra.NonUnitalSubalgebra//instructions: -2.5G (-3.86%)
  • build/module/Mathlib.Algebra.Algebra.Subalgebra.Basic//instructions: -2.1G (-4.79%)
  • build/module/Mathlib.Algebra.Algebra.Tower//instructions: -2.0G (-9.90%)
  • build/module/Mathlib.Algebra.Category.ModuleCat.Differentials.Presheaf//instructions: -1.6G (-5.20%)
  • build/module/Mathlib.Algebra.Category.ModuleCat.Presheaf.Sheafify//instructions: -1.8G (-3.62%)
  • build/module/Mathlib.Algebra.Category.ModuleCat.Sheaf.Free//instructions: -1.0G (-4.80%)
  • build/module/Mathlib.Algebra.Homology.ShortComplex.Homology//instructions: -1.8G (-5.16%)
  • build/module/Mathlib.Algebra.Lie.Abelian//instructions: -1.4G (-5.14%)
  • build/module/Mathlib.Algebra.Lie.Ideal//instructions: -3.4G (-13.25%)
  • build/module/Mathlib.Algebra.Lie.IdealOperations//instructions: -1.6G (-8.48%)
  • build/module/Mathlib.Algebra.Lie.Nilpotent//instructions: -2.3G (-4.77%)
  • build/module/Mathlib.Algebra.Lie.Subalgebra//instructions: -1.7G (-4.82%)
  • build/module/Mathlib.Algebra.Module.Presentation.Basic//instructions: -1.3G (-5.66%)
  • build/module/Mathlib.Algebra.Module.Submodule.Defs//instructions: -785.6M (-5.54%)
  • build/module/Mathlib.Algebra.Polynomial.Basic//instructions: -2.0G (-5.24%)
  • build/module/Mathlib.Algebra.Polynomial.Div//instructions: -1.3G (-3.81%)
  • build/module/Mathlib.Algebra.Polynomial.Eval.Defs//instructions: -2.5G (-9.94%)
  • build/module/Mathlib.Algebra.Polynomial.Roots//instructions: -1.7G (-4.13%)
  • build/module/Mathlib.Algebra.Ring.Subring.Basic//instructions: -2.9G (-6.03%)
  • and 42 more

@github-actions github-actions Bot added toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN mathlib4-nightly-available A branch for this PR exists at leanprover-community/mathlib4-nightly-testing:lean-pr-testing-NNNN labels Jul 29, 2026
@leanprover-bot leanprover-bot added the builds-manual CI has verified that the Lean Language Reference builds against this PR label Jul 29, 2026
@leanprover-bot

leanprover-bot commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Reference manual CI status:

  • ✅ Reference manual branch lean-pr-testing-14595 has successfully built against this PR. (2026-07-29 16:28:51) View Log
  • 🟡 Reference manual branch lean-pr-testing-14595 build against this PR didn't complete normally. (2026-07-29 16:30:13) View Log
  • ❗ Reference manual CI will not be attempted unless your PR branches off the nightly-with-manual branch. Try git rebase c8e19cca2547a89c3aba401afaab9a8808f490a2 --onto e991a05e359a25988f49bff3ab8af986e959b866. You can force reference manual CI using the force-manual-ci label. (2026-08-31 20:21:01)
  • ❗ Reference manual CI can not be attempted yet, as the nightly-testing-2026-08-31 tag does not exist there yet. We will retry when you push more commits. If you rebase your branch onto nightly-with-manual, reference manual CI should run now. You can force reference manual CI using the force-manual-ci label. (2026-08-31 23:42:35)

@mathlib-lean-pr-testing mathlib-lean-pr-testing Bot added the builds-mathlib CI has verified that Mathlib builds against this PR label Jul 29, 2026
@mathlib-lean-pr-testing

mathlib-lean-pr-testing Bot commented Jul 29, 2026

Copy link
Copy Markdown

Mathlib CI status (docs):

  • ✅ Mathlib branch lean-pr-testing-14595 has successfully built against this PR. (2026-07-29 17:29:17) View Log
  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase c8e19cca2547a89c3aba401afaab9a8808f490a2 --onto 138ca9f20763523c4093baa092cf371e89535098. You can force Mathlib CI using the force-mathlib-ci label. (2026-08-31 20:20:59)
  • ✅ Mathlib branch lean-pr-testing-14595 has successfully built against this PR. (2026-09-01 00:45:02) View Log

@marcelolynch
marcelolynch force-pushed the sectionvars-cache-pr branch from dc65ebd to c393a43 Compare July 29, 2026 19:23
@marcelolynch

Copy link
Copy Markdown
Contributor Author

!bench mathlib

@leanprover-radar

Copy link
Copy Markdown

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

  • build//instructions: -391.9G (-0.27%)

Large changes (2✅)

  • build/module/Mathlib.Algebra.Star.NonUnitalSubalgebra//instructions: -21.1G (-20.66%)
  • and 1 hidden

Medium changes (11✅, 1🟥)

  • build/module/Mathlib.Algebra.Algebra.Equiv//instructions: -3.8G (-9.72%)
  • build/module/Mathlib.Algebra.Lie.Basic//instructions: -4.7G (-9.75%)
  • build/module/Mathlib.Algebra.Lie.Submodule//instructions: -4.8G (-8.69%)
  • 🟥 build/module/Mathlib.AlgebraicTopology.SimplicialSet.NerveAdjunction//instructions: +19.6G (+20.83%)
  • build/module/Mathlib.Analysis.Calculus.ContDiff.Defs//instructions: -10.7G (-9.92%)
  • build/module/Mathlib.Analysis.Calculus.ContDiff.FTaylorSeries//instructions: -15.8G (-13.12%)
  • build/module/Mathlib.Analysis.Calculus.FormalMultilinearSeries//instructions: -7.4G (-17.84%)
  • build/module/Mathlib.Analysis.Convolution//instructions: -13.8G (-12.15%)
  • build/module/Mathlib.LinearAlgebra.TensorProduct.Tower//instructions: -22.3G (-15.83%)
  • build/module/Mathlib.RepresentationTheory.Continuous.TopRep//instructions: -4.3G (-9.78%)
  • build/module/Mathlib.SetTheory.Cardinal.Cofinality.Club//instructions: -5.4G (-18.63%)
  • build/module/Mathlib.Topology.MetricSpace.IsometricSMul//instructions: -2.5G (-9.47%)

Small changes (62✅)

  • build/module/Mathlib.Algebra.Algebra.Hom//instructions: -1.3G (-6.64%)
  • build/module/Mathlib.Algebra.Algebra.NonUnitalSubalgebra//instructions: -2.5G (-3.86%)
  • build/module/Mathlib.Algebra.Algebra.Subalgebra.Basic//instructions: -2.1G (-4.79%)
  • build/module/Mathlib.Algebra.Algebra.Tower//instructions: -2.0G (-9.90%)
  • build/module/Mathlib.Algebra.Category.ModuleCat.Differentials.Presheaf//instructions: -1.6G (-5.20%)
  • build/module/Mathlib.Algebra.Category.ModuleCat.Presheaf.Sheafify//instructions: -1.8G (-3.62%)
  • build/module/Mathlib.Algebra.Category.ModuleCat.Sheaf.Free//instructions: -1.0G (-4.80%)
  • build/module/Mathlib.Algebra.Homology.ShortComplex.Homology//instructions: -1.8G (-5.16%)
  • build/module/Mathlib.Algebra.Lie.Abelian//instructions: -1.4G (-5.14%)
  • build/module/Mathlib.Algebra.Lie.Ideal//instructions: -3.4G (-13.25%)
  • build/module/Mathlib.Algebra.Lie.IdealOperations//instructions: -1.6G (-8.48%)
  • build/module/Mathlib.Algebra.Lie.Nilpotent//instructions: -2.3G (-4.77%)
  • build/module/Mathlib.Algebra.Lie.Subalgebra//instructions: -1.7G (-4.82%)
  • build/module/Mathlib.Algebra.Module.Presentation.Basic//instructions: -1.3G (-5.66%)
  • build/module/Mathlib.Algebra.Module.Submodule.Defs//instructions: -785.6M (-5.54%)
  • build/module/Mathlib.Algebra.Polynomial.Basic//instructions: -2.0G (-5.24%)
  • build/module/Mathlib.Algebra.Polynomial.Div//instructions: -1.3G (-3.81%)
  • build/module/Mathlib.Algebra.Polynomial.Eval.Defs//instructions: -2.5G (-9.94%)
  • build/module/Mathlib.Algebra.Polynomial.Roots//instructions: -1.7G (-4.13%)
  • build/module/Mathlib.Algebra.Ring.Subring.Basic//instructions: -2.9G (-6.03%)
  • and 42 more

@marcelolynch

Copy link
Copy Markdown
Contributor Author

!bench mathlib

@leanprover-radar

Copy link
Copy Markdown

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

  • build//instructions: -391.9G (-0.27%)

Large changes (2✅)

  • build/module/Mathlib.Algebra.Star.NonUnitalSubalgebra//instructions: -21.1G (-20.66%)
  • and 1 hidden

Medium changes (11✅, 1🟥)

  • build/module/Mathlib.Algebra.Algebra.Equiv//instructions: -3.8G (-9.72%)
  • build/module/Mathlib.Algebra.Lie.Basic//instructions: -4.7G (-9.75%)
  • build/module/Mathlib.Algebra.Lie.Submodule//instructions: -4.8G (-8.69%)
  • 🟥 build/module/Mathlib.AlgebraicTopology.SimplicialSet.NerveAdjunction//instructions: +19.6G (+20.83%)
  • build/module/Mathlib.Analysis.Calculus.ContDiff.Defs//instructions: -10.7G (-9.92%)
  • build/module/Mathlib.Analysis.Calculus.ContDiff.FTaylorSeries//instructions: -15.8G (-13.12%)
  • build/module/Mathlib.Analysis.Calculus.FormalMultilinearSeries//instructions: -7.4G (-17.84%)
  • build/module/Mathlib.Analysis.Convolution//instructions: -13.8G (-12.15%)
  • build/module/Mathlib.LinearAlgebra.TensorProduct.Tower//instructions: -22.3G (-15.83%)
  • build/module/Mathlib.RepresentationTheory.Continuous.TopRep//instructions: -4.3G (-9.78%)
  • build/module/Mathlib.SetTheory.Cardinal.Cofinality.Club//instructions: -5.4G (-18.63%)
  • build/module/Mathlib.Topology.MetricSpace.IsometricSMul//instructions: -2.5G (-9.47%)

Small changes (62✅)

  • build/module/Mathlib.Algebra.Algebra.Hom//instructions: -1.3G (-6.64%)
  • build/module/Mathlib.Algebra.Algebra.NonUnitalSubalgebra//instructions: -2.5G (-3.86%)
  • build/module/Mathlib.Algebra.Algebra.Subalgebra.Basic//instructions: -2.1G (-4.79%)
  • build/module/Mathlib.Algebra.Algebra.Tower//instructions: -2.0G (-9.90%)
  • build/module/Mathlib.Algebra.Category.ModuleCat.Differentials.Presheaf//instructions: -1.6G (-5.20%)
  • build/module/Mathlib.Algebra.Category.ModuleCat.Presheaf.Sheafify//instructions: -1.8G (-3.62%)
  • build/module/Mathlib.Algebra.Category.ModuleCat.Sheaf.Free//instructions: -1.0G (-4.80%)
  • build/module/Mathlib.Algebra.Homology.ShortComplex.Homology//instructions: -1.8G (-5.16%)
  • build/module/Mathlib.Algebra.Lie.Abelian//instructions: -1.4G (-5.14%)
  • build/module/Mathlib.Algebra.Lie.Ideal//instructions: -3.4G (-13.25%)
  • build/module/Mathlib.Algebra.Lie.IdealOperations//instructions: -1.6G (-8.48%)
  • build/module/Mathlib.Algebra.Lie.Nilpotent//instructions: -2.3G (-4.77%)
  • build/module/Mathlib.Algebra.Lie.Subalgebra//instructions: -1.7G (-4.82%)
  • build/module/Mathlib.Algebra.Module.Presentation.Basic//instructions: -1.3G (-5.66%)
  • build/module/Mathlib.Algebra.Module.Submodule.Defs//instructions: -785.6M (-5.54%)
  • build/module/Mathlib.Algebra.Polynomial.Basic//instructions: -2.0G (-5.24%)
  • build/module/Mathlib.Algebra.Polynomial.Div//instructions: -1.3G (-3.81%)
  • build/module/Mathlib.Algebra.Polynomial.Eval.Defs//instructions: -2.5G (-9.94%)
  • build/module/Mathlib.Algebra.Polynomial.Roots//instructions: -1.7G (-4.13%)
  • build/module/Mathlib.Algebra.Ring.Subring.Basic//instructions: -2.9G (-6.03%)
  • and 42 more

@marcelolynch
marcelolynch force-pushed the sectionvars-cache-pr branch 2 times, most recently from 0cbb9f9 to 407548a Compare August 31, 2026 20:23
@marcelolynch

Copy link
Copy Markdown
Contributor Author

!bench mathlib

@leanprover-radar

Copy link
Copy Markdown

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

  • build//instructions: -391.9G (-0.27%)

Large changes (5✅)

  • build/module/Mathlib.Algebra.Star.NonUnitalSubalgebra//instructions: -21.1G (-20.66%)
  • build/module/Mathlib.Analysis.Calculus.ContDiff.Defs//instructions: -10.7G (-9.92%)
  • build/module/Mathlib.Analysis.Calculus.FormalMultilinearSeries//instructions: -7.4G (-17.84%)
  • build/module/Mathlib.LinearAlgebra.TensorProduct.Tower//instructions: -22.3G (-15.83%)
  • and 1 hidden

Medium changes (37✅, 1🟥)

  • build/module/Mathlib.Algebra.Algebra.Equiv//instructions: -3.8G (-9.72%) (reduced significance based on absolute threshold)
  • build/module/Mathlib.Algebra.Algebra.Hom//instructions: -1.3G (-6.64%)
  • build/module/Mathlib.Algebra.Algebra.NonUnitalSubalgebra//instructions: -2.5G (-3.86%)
  • build/module/Mathlib.Algebra.Algebra.Subalgebra.Basic//instructions: -2.1G (-4.79%)
  • build/module/Mathlib.Algebra.Algebra.Tower//instructions: -2.0G (-9.90%)
  • build/module/Mathlib.Algebra.Homology.ShortComplex.Homology//instructions: -1.8G (-5.16%)
  • build/module/Mathlib.Algebra.Lie.Abelian//instructions: -1.4G (-5.14%)
  • build/module/Mathlib.Algebra.Lie.Basic//instructions: -4.7G (-9.75%) (reduced significance based on absolute threshold)
  • build/module/Mathlib.Algebra.Lie.Ideal//instructions: -3.4G (-13.25%)
  • build/module/Mathlib.Algebra.Lie.Nilpotent//instructions: -2.3G (-4.77%)
  • build/module/Mathlib.Algebra.Lie.Subalgebra//instructions: -1.7G (-4.82%)
  • build/module/Mathlib.Algebra.Lie.Submodule//instructions: -4.8G (-8.69%)
  • build/module/Mathlib.Algebra.Module.Presentation.Basic//instructions: -1.3G (-5.66%)
  • build/module/Mathlib.Algebra.Polynomial.Basic//instructions: -2.0G (-5.24%)
  • 🟥 build/module/Mathlib.AlgebraicTopology.SimplicialSet.NerveAdjunction//instructions: +19.6G (+20.83%)
  • build/module/Mathlib.Analysis.BoxIntegral.Basic//instructions: -4.2G (-7.34%)
  • build/module/Mathlib.Analysis.Calculus.ContDiff.Convolution//instructions: -2.9G (-4.50%)
  • build/module/Mathlib.Analysis.Calculus.ContDiff.FTaylorSeries//instructions: -15.8G (-13.12%)
  • build/module/Mathlib.Analysis.Calculus.Deriv.Basic//instructions: -3.4G (-6.49%)
  • build/module/Mathlib.Analysis.Convolution//instructions: -13.8G (-12.15%)
  • and 18 more

Small changes (116✅, 109🟥)

  • 🟥 build/module/Aesop.Builder.Basic//instructions: +36.6M (+2.02%)
  • 🟥 build/module/Aesop.Builder.NormSimp//instructions: +25.1M (+1.39%)
  • 🟥 build/module/Aesop.BuiltinRules.Rfl//instructions: +26.8M (+1.73%)
  • 🟥 build/module/Aesop.BuiltinRules.Subst//instructions: +46.6M (+1.74%)
  • 🟥 build/module/Aesop.EMap//instructions: +37.5M (+1.19%)
  • 🟥 build/module/Aesop.ElabM//instructions: +40.0M (+2.78%)
  • 🟥 build/module/Aesop.Exception//instructions: +28.5M (+1.94%)
  • 🟥 build/module/Aesop.Forward.PremiseIndex//instructions: +24.0M (+2.14%)
  • 🟥 build/module/Aesop.Forward.State.Initial//instructions: +39.0M (+1.98%)
  • 🟥 build/module/Aesop.Index.DiscrTreeConfig//instructions: +32.0M (+2.79%)
  • 🟥 build/module/Aesop.Percent//instructions: +33.1M (+2.63%)
  • 🟥 build/module/Aesop.Rule.Basic//instructions: +35.1M (+2.45%)
  • 🟥 build/module/Aesop.RuleSet.Filter//instructions: +34.0M (+2.61%)
  • 🟥 build/module/Aesop.RuleSet.Member//instructions: +29.0M (+1.77%)
  • 🟥 build/module/Aesop.RuleTac.Forward.Basic//instructions: +38.4M (+1.78%)
  • 🟥 build/module/Aesop.RuleTac.Preprocess//instructions: +32.5M (+2.38%)
  • 🟥 build/module/Aesop.Script.Check//instructions: +29.4M (+1.77%)
  • 🟥 build/module/Aesop.Script.ScriptM//instructions: +35.4M (+2.22%)
  • 🟥 build/module/Aesop.Script.Step//instructions: +33.5M (+0.93%)
  • 🟥 build/module/Aesop.Script.UScript//instructions: +29.8M (+1.89%)
  • and 205 more

@marcelolynch

Copy link
Copy Markdown
Contributor Author

!bench

@leanprover-radar

leanprover-radar commented Aug 31, 2026

Copy link
Copy Markdown

Benchmark results for 407548a against c8e19cc are in. There are significant results. @marcelolynch

  • build//instructions: -38.5G (-0.34%)

Large changes (2✅)

  • build/module/Std.Data.DHashMap.Lemmas//instructions: -5.4G (-10.45%)
  • build/module/Std.Data.DTreeMap.Internal.Lemmas//instructions: -6.3G (-2.92%)

Medium changes (13✅)

  • build/module/Std.Data.DHashMap.Internal.RawLemmas//instructions: -2.8G (-1.16%)
  • build/module/Std.Data.DHashMap.RawLemmas//instructions: -3.3G (-2.26%)
  • build/module/Std.Data.DTreeMap.Lemmas//instructions: -4.5G (-8.05%) (reduced significance based on absolute threshold)
  • build/module/Std.Data.DTreeMap.Raw.Lemmas//instructions: -4.3G (-6.64%) (reduced significance based on absolute threshold)
  • build/module/Std.Data.ExtDHashMap.Lemmas//instructions: -3.5G (-7.41%) (reduced significance based on absolute threshold)
  • build/module/Std.Data.ExtDTreeMap.Lemmas//instructions: -3.1G (-6.45%) (reduced significance based on absolute threshold)
  • build/module/Std.Data.ExtHashMap.Lemmas//instructions: -1.7G (-6.96%) (reduced significance based on absolute threshold)
  • build/module/Std.Data.ExtTreeMap.Lemmas//instructions: -1.2G (-4.25%) (reduced significance based on absolute threshold)
  • build/module/Std.Data.HashMap.Lemmas//instructions: -2.6G (-8.87%) (reduced significance based on absolute threshold)
  • build/module/Std.Data.TreeMap.Lemmas//instructions: -1.7G (-5.78%) (reduced significance based on absolute threshold)
  • build/module/Std.Data.TreeMap.Raw.Lemmas//instructions: -1.6G (-4.46%) (reduced significance based on absolute threshold)
  • misc/import Std.Data.DHashMap.Internal.RawLemmas//instructions: -2.2G (-1.03%)
  • size/all/.olean//bytes: -1MiB (-0.44%)

Small changes (42✅, 54🟥)

  • build/module/Init.Control.Lawful.MonadLift.Lemmas//instructions: -30.4M (-3.49%)
  • 🟥 build/module/Init.Conv//instructions: +52.3M (+1.41%)
  • 🟥 build/module/Init.Core//instructions: +42.2M (+0.43%)
  • 🟥 build/module/Init.Data.Array.Attach//instructions: +38.0M (+0.38%)
  • 🟥 build/module/Init.Data.Array.Basic//instructions: +34.2M (+0.32%)
  • 🟥 build/module/Init.Data.Array.Find//instructions: +43.3M (+0.45%)
  • 🟥 build/module/Init.Data.Array.Lemmas//instructions: +251.0M (+0.48%)
  • 🟥 build/module/Init.Data.Array.Range//instructions: +18.9M (+0.48%)
  • 🟥 build/module/Init.Data.Bool//instructions: +70.7M (+1.75%)
  • 🟥 build/module/Init.Data.ByteArray.Lemmas//instructions: +25.6M (+0.48%)
  • 🟥 build/module/Init.Data.Fin.Lemmas//instructions: +99.1M (+0.93%)
  • 🟥 build/module/Init.Data.Float.Model.Float//instructions: +15.9M (+1.63%)
  • 🟥 build/module/Init.Data.Float.Model.Float32//instructions: +14.8M (+1.51%)
  • 🟥 build/module/Init.Data.Int.DivMod.Lemmas//instructions: +168.0M (+0.46%)
  • 🟥 build/module/Init.Data.Int.Gcd//instructions: +66.5M (+1.52%)
  • 🟥 build/module/Init.Data.Int.Lemmas//instructions: +48.2M (+1.02%)
  • 🟥 build/module/Init.Data.Int.Order//instructions: +112.7M (+1.27%)
  • 🟥 build/module/Init.Data.List.Lemmas//instructions: +213.6M (+0.57%)
  • 🟥 build/module/Init.Data.List.MinMax//instructions: +21.4M (+0.60%)
  • 🟥 build/module/Init.Data.Nat.Basic//instructions: +101.6M (+1.46%) (reduced significance based on absolute threshold)
  • and 76 more

marcelolynch and others added 2 commits August 31, 2026 16:23
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A reuse of the cached section variables reopens the telescope, which makes new free variables. The language server finds the binder of a free variable through its info node, so the reuse path adds a binder info node for each new free variable. It takes the binder syntax from `Term.elabBindersEx` and adds the nodes with `Term.addLocalVarInfo`, as `MutualDef` does after it reopens the telescope of a declaration. Without the nodes, go-to-definition, document highlight and find-references stop working on the section variables.

The cache key also holds the revision of the default instance table. `attribute [default_instance]` changes the synthesis that runs inside the binder types without a change of the instance table, so the key alone could keep a stale elaboration.

A scope without section variables skips the cache. Such a scope has nothing to reuse, and the work of the cache costs more than the elaboration of the empty block.

The cache also stores a negative outcome. A block whose elaboration a telescope cannot reproduce, for example a block that auto-binds a universe name, built and discarded a telescope for every command of the scope. The cache now records the outcome once, and the later commands elaborate the binders without that work.

The cache takes one field of the command state. A named `SectionVarsCacheKey` holds the scope and the two revisions, and both the stored entry and the last miss use it, after the `SynthInstanceCacheKey` convention. The number of section variables bounds the reopened telescope.

Add tests for the type-class synthesis that finds a section-variable instance on the reuse path, the binder annotations, the erasure of an instance, the auto-bound implicit blocks, the temporary scope of a `set_option ... in` prefix, and the invalidation by a default instance. Add a server test for go-to-definition and document highlight on a section variable.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
mathlib-nightly-testing Bot pushed a commit to leanprover-community/batteries that referenced this pull request Aug 31, 2026
mathlib-nightly-testing Bot pushed a commit to leanprover-community/mathlib4-nightly-testing that referenced this pull request Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

builds-manual CI has verified that the Lean Language Reference builds against this PR builds-mathlib CI has verified that Mathlib builds against this PR mathlib4-nightly-available A branch for this PR exists at leanprover-community/mathlib4-nightly-testing:lean-pr-testing-NNNN toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants