Skip to content

perf: carry the 0.10.0 performance fixes to main - #1028

Closed
devin-ai-integration[bot] wants to merge 10 commits into
mainfrom
hotfix/perf-0.10.0
Closed

devin-ai-integration[bot] wants to merge 10 commits into
mainfrom
hotfix/perf-0.10.0

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

What and why

The release-gate performance measurement of 0.10.0 against 0.9.2 found five regressions whose cost was avoidable rather than the price of a feature, and develop fixed them in six pull requests after the release branch was cut (#1017, #1018, #1019, #1021, #1022, #1023). This hotfix carries those fixes to main before 0.10.0 is tagged, as cherry-picks (-x) in their original order, with their changelog fragments folded into the already-dated 0.10.0 ### Performance section as the previous hotfix did. No other change.

  • ParseFile/ParseSources/GetDiagnostics convert a cached model's diagnostics to protobuf once instead of on every call (the Annex A vehicle example carries 134 warnings; GRPCParseFileCached had gone from 22 to 299 allocations).
  • The symbol index's registration snapshot shares the index's re-export claim tables instead of deep-copying them per name (workspace edits had 2–4× the bytes of 0.9.2).
  • The body-write binding check formats its description only on refusal (a third of the new allocations per executed step).
  • The succession-cycle check is memoized while no behavior is held (10% of BatchConstraints CPU).
  • Compiled calc scalars are packed into three words and the holds check is decided at compile time (Fib(25) interpreted had gone 8 → 41 ms).
  • this/that/isActive recognition compares the owner chain instead of building a qualified name.

Specification basis

No behaviour change; every result, diagnostic and step count is unchanged (the pull requests above pin that).

How it was verified

Cherry-picks applied without conflict. Locally on the branch: go build ./..., go vet ./..., gofmt -l . (empty), and go test -count=1 over internal/frontend/grpc, internal/semantic/..., internal/exec/runtime/..., internal/workspace/..., internal/check/..., internal/frontend/lsp, internal/frontend/repl, tests/grpc, tests/perf, tests/resolve; python3 scripts/changelog.py check. The measurement of this branch against v0.9.2 is the record in #1015, which is being redone against it.

Checklist

  • make test and make lint pass locally (the packages the picks touch; CI runs the full race suite)
  • Tests added or updated for the change (carried by the cherry-picks)
  • Documentation extended where it already covers the surface (see CONTRIBUTING.md)
  • Changelog entry added as changes/unreleased/<slug>.<section>.md, not as an edit to CHANGELOG.md — the fragments are folded into the dated 0.10.0 section, as a hotfix on main must
  • baselines regenerated and make docs-counts run if a gate count moved (none moved)
  • No internal work-item labels (waves, slices, F4, K5) in the body, docs, or changelog

devin-ai-integration Bot and others added 10 commits October 9, 2026 12:06
Co-Authored-By: jason.han <hanhuijun@gmail.com>
(cherry picked from commit 70242d8)
Co-Authored-By: jason.han <hanhuijun@gmail.com>
(cherry picked from commit e4fde53)
…the read-only contract

Co-Authored-By: jason.han <hanhuijun@gmail.com>
(cherry picked from commit 24aaa39)
Co-Authored-By: jason.han <hanhuijun@gmail.com>
(cherry picked from commit c6bdb49)
Before a name's registration changes, the index notes what a lookup of it
reads so that one registered again as it was is not a change. The note held
a deep copy of every document's re-export claims and routes on the name,
taken once per name a replaced document re-registers.

A claims map and the claims in it are now never written once installed: a
write installs a new map, so the note shares the index's own tables. What
counts as a change is unchanged; tests pin the comparison and the resolver
invalidations an edit of a re-exporting document reports.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
(cherry picked from commit 4b4b351)
…ck refuses it

The binding check of an assignment or declaration in an action, state or
calculation body took the description of where it ran as a string built on
every write, whether or not the check failed. checkAssignable,
checkNamedWriteAs and checkBodyDeclarationAs now take a func() string and
format it only in the refusal they report; the hot callers pass the host's
describe method, and the action's own label and a node's description are
built the same way.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
(cherry picked from commit 37b4a17)
…s held

The cycle walk over held behaviors ran on every quiescent scan, which a constraint check reaches once per check. Remember that no behavior is held under a count of the behaviors that ever entered held, moved by the deferred behavior constructor and by snapshot restore, and answer nil from the memo until that count moves.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
(cherry picked from commit 8bd97fc)
The compiled calc tier held each scalar in 56 bytes and, for every parameter, local and result, boxed it back into the evaluator's constant to decide whether the declaration holds it, building the diagnostic a refusal would name whether or not one followed. A scalar is now the constant packed into 24 bytes (semantics.Packed), unpacked without allocating; which kinds a declaration holds whatever the value is decided once at compile time; the diagnostic is built only on refusal; and the step charge inlines into every node. Results, promotions, refusals, error messages and step counts are unchanged.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
(cherry picked from commit 4a1b937)
IsStateActivity, IsBaseThat and IsOccurrenceThis asked for a target's
fully-qualified name on every feature-chain read to compare it against
a known name; they now match the owner chain segment by segment with
symbols.HasFQN, so a conformant body allocates nothing for the question.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
(cherry picked from commit 367ca7e)
Co-Authored-By: jason.han <hanhuijun@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration
devin-ai-integration Bot changed the base branch from develop to main October 9, 2026 12:14
@devin-ai-integration devin-ai-integration Bot reopened this Oct 9, 2026
@devin-ai-integration
devin-ai-integration Bot marked this pull request as ready for review October 9, 2026 13:19

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

Devin Review

Comment thread internal/frontend/grpc/cache.go
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Superseded by #1024 (hotfix/0.10.0-develop-sync), which already carries these six performance fixes along with the rest of develop's post-cut changes.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant