Skip to content

perf: cache the innermost scope state in ScopedEnvExtension.StateStack - #14968

Draft
Kha wants to merge 1 commit into
masterfrom
scoped-ext-cached-state
Draft

perf: cache the innermost scope state in ScopedEnvExtension.StateStack#14968
Kha wants to merge 1 commit into
masterfrom
scoped-ext-cached-state

Conversation

@Kha

@Kha Kha commented Aug 29, 2026

Copy link
Copy Markdown
Member

ScopedEnvExtension.getState is called on hot paths such as parsing, attribute lookup and simp set lookup, and had to walk into the head of stateStack and project State.state out of it, with reference counting on both intermediates. Cache that state in a new StateStack.state field so the lookup is a single projection, and keep it in sync in the (much colder) functions that push, pop or update the stack. The empty-stack unreachable! disappears with it.

Because StateStack now stores a σ, its Inhabited instance depends on Inhabited σ and would have to be rebuilt, and hence allocated, on every getState call. ScopedEnvExtension therefore stores the witness in a defaultState field, built once at registration, which is why registerScopedEnvExtension now takes [Inhabited σ]; all existing callers already have that instance. Inhabited is erased at runtime, so getState just reads the field.

`ScopedEnvExtension.getState` is called on hot paths such as parsing, attribute lookup and simp set lookup, and had to walk into the head of `stateStack` and project `State.state` out of it, with reference counting on both intermediates. Cache that state in a new `StateStack.state` field so the lookup is a single projection, and keep it in sync in the (much colder) functions that push, pop or update the stack. The empty-stack `unreachable!` disappears with it.

Because `StateStack` now stores a `σ`, its `Inhabited` instance depends on `Inhabited σ` and would have to be rebuilt, and hence allocated, on every `getState` call. `ScopedEnvExtension` therefore stores the witness in a `defaultState` field, built once at registration, which is why `registerScopedEnvExtension` now takes `[Inhabited σ]`; all existing callers already have that instance. `Inhabited` is erased at runtime, so `getState` just reads the field.

Changing the layout of `StateStack` breaks the stage1 build (segfaults and corrupted parser state in modules that define and use meta code in the same file), so `interpreter.prefer_native` is enabled in `stage0/src/stdlib_flags.h` as described in `doc/dev/bootstrap.md`.
@Kha

Kha commented Aug 29, 2026

Copy link
Copy Markdown
Member Author

!bench

@leanprover-radar

leanprover-radar commented Aug 29, 2026

Copy link
Copy Markdown

Benchmark results for d1863d1 against e991a05 are in. No significant results found. @Kha

  • build//instructions: -2.1G (-0.02%)

Small changes (2✅, 1🟥)

  • build/module/Lean.Data.Lsp.Capabilities//instructions: -65.1M (-1.91%)
  • build/module/Lean.Language.Basic//instructions: -64.0M (-2.25%) (reduced significance based on absolute threshold)
  • 🟥 build/module/Lean.ScopedEnvExtension//instructions: +65.7M (+2.21%)

@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 Aug 29, 2026
@leanprover-bot leanprover-bot added the builds-manual CI has verified that the Lean Language Reference builds against this PR label Aug 29, 2026
@leanprover-bot

leanprover-bot commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

Reference manual CI status:

@mathlib-lean-pr-testing mathlib-lean-pr-testing Bot added the breaks-mathlib This is not necessarily a blocker for merging: but there needs to be a plan label Aug 29, 2026
@mathlib-lean-pr-testing

Copy link
Copy Markdown

Mathlib CI status (docs):

@Kha

Kha commented Aug 29, 2026

Copy link
Copy Markdown
Member Author

!bench mathlib

@leanprover-radar

Copy link
Copy Markdown

Benchmarking leanprover-community/mathlib4-nightly-testing@d40ae5d against leanprover-community/mathlib4-nightly-testing@78f2465 (preliminary results).

React with 👀 to be notified when the results are in. The command author is always notified.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaks-mathlib This is not necessarily a blocker for merging: but there needs to be a plan builds-manual CI has verified that the Lean Language Reference 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