Skip to content

perf: establish the simpler service source baseline - #2

Merged
deiteris merged 9 commits into
masterfrom
refactor/service-source-simple
Oct 10, 2026
Merged

deiteris merged 9 commits into
masterfrom
refactor/service-source-simple

Conversation

@deiteris

@deiteris deiteris commented Oct 10, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Land the independently useful typed navigation, postparse include fix, decoder-owned compatibility facts and visible-name enumeration.
  • Keep routine service snapshots text-only by default.
  • Cache and share queried plain source trees across hover/inlays/folding/selection, with weak owner lifetime, failure memoization, input/policy compatibility and stale-view protection.
  • Preserve the parked record-backed replacement without merging it.

Acceptance

The remaining trade-offs are accepted for merge-then-recover. Against measurement-only master d2b8a02 (rewritten as e81d361):

  • large/service rebuild time within noise; peak -20.1%, retained -24.0%.
  • Three-cycle mixed workloads -57.5% / -58.9% time, peak -25.0% / -31.1%; post-query retained +5.4%.
  • The mixed corpus is one 304 KiB / 13204-line file; these are THREE edit/query cycles, not one request.
  • Cold hover/inlay workloads retain the accepted +23% first-use composition cost. The next selective port targets model-backed inlays.

Verification

Full Windows gate: 5838 passed, 68 skipped, 1 xfailed; strict mypy, Ruff and formatting pass. Source-structure and both mixed linearity checks pass. Fourteen focused source-ownership cases cover request order, errors, policy, old snapshots and release. Linux, pure-Python YAML, TCK and full CI must pass before merge.

Plan and evidence

See docs/research/2026-10-10/service-recovery-plan.md and docs/reports/2026-10-10/service-baseline-integration.md. The untracked handoff is excluded.

load_include serves readers outside the parse, such as join comparing a
target the parse never read (docs/20 § 2). It composes through
_compose_include, which stored the decoded text in raml.source_texts
whenever retain_text was on, contrary to its documented contract that
such reads enter none of the parse's caches. A post-parse write could
grow the read set of an already built snapshot.

Add a store_text switch to _compose_include; load_include passes False.
RAML 1.0 deprecates the schemas: table and the schema: facet. The
decoders that accept those spellings now record each accepted use in
Raml.syntax_aliases, keyed by the declaring entity's ID (docs/04 § 5,
docs/05 § 3). The record holds the authored URI, the key's position and
the spelling itself; it keeps no YAML node (docs/13 § 3).

deprecated-schemas reads those records instead of walking every
declaration's retained tree, so it is no longer a source-sensitive rule
(docs/18 § 6). No rule in the default set now requires retained trees;
the language service's snapshots therefore parse with text alone unless
an opt-in style rule is enabled (docs/21 § 2).

The retired docs/15 paragraph proposed exactly this recording. The three
opt-in style rules that do read trees are named in docs/18.

Bench (ab 2b6502e, 3 rounds): hover time +27.1% (noise 3.3%), peak
+16.6%, kept +4.0%; inlays time +21.9% (noise 4.8%), peak +12.9%, kept
+3.3%. The snapshots no longer retain parse trees, so the first hover or
inlay per snapshot composes the queried file on demand, about a third of
a parse of it; repeated queries are cached. Memory: large/service peak
-20.5%, kept -24.4%; effective-types kept -27.5%. Accepted with a
revisit note in docs/15 § 2.
…lection

Folding and selection composed the buffer's whole document on every request
(docs/21 § 4). The workspace now composes a file's current text once and
holds the tree, invalidated with the buffer on change, close or a disk
change; Workspace.source answers both request kinds. The text-based
folding_ranges and selection_ranges keep their one-shot, per-call
composition. The source-structure reach test also counts compose calls:
each measured pass composes the text once, shared by its fifteen requests.

Bench (ab 2b6502e, 3 rounds): no existing workload moves beyond its
noise; the hover and inlays first-use deltas belong to the preceding
commit and are documented in docs/15 § 2. New source-structure workload,
linearity over 3 repeats: time 1.004, peak 0.998, retained 1.000.
See docs/reports/2026-10-10/service-source-simple-rework.md.
The parse-side compatibility recording (docs/18 § 6) only runs on
`schemas:` and `schema:`, which no bench corpus used, so the parse
workloads never measured it. Every other `large` library now declares
its whole table under the `schemas:` alias (a fragment takes one table
or the other), every other inherited type uses the `schema:` facet, the
`large` root carries a `schemas:` table of its own, and `endpoints`
declares its payload type in a `schemas:` table with every fourth body
typed by `schema:`. A reach test pins that both corpora record both
spellings.

Bench (ab 2b6502e, 3 rounds, on the spelling-carrying corpora): time
within noise on large (all eight configurations), endpoints and small
(parse, unwrap, unwrap+lint). Allocation peak and kept move +0.4 to
+0.8 percent on the configurations that hold the model — the
syntax_aliases records themselves, about 1.3 thousand of them, roughly
120 KB on large. large/service: time noise, peak -20.1%, kept -24.0%.
Merge the portable benchmark and profiling plan without changing the simpler production implementation. Record the master-controlled mixed-request result: service-session time -49.8% beyond 4.4% noise, peak +2.1%, kept +26.8%; source-first time -52.7% beyond 18.9% noise, peak -10.9%, kept +26.9%. Duplicate source ownership blocks acceptance and is the next isolated fix.

The Windows gate passes: 5824 passed, 68 skipped, 1 xfailed. Measurement-only PR 1 passed all CI checks and merged as d2b8a02.
Use one workspace-owned plain tree for compatible hover/inlay and folding/selection inputs. Cache failures and include depth/backend policy in compatibility. Snapshots borrow the owner weakly; stale input misses cannot replace current entries, while unrelated edits and unchanged dependencies can reuse source. Preserve full-source originals and separate JSON normalization.

Against 94ebc60, service-session/unwrap time -12.5% beyond 2.8% noise, peak -26.5%, kept -16.9%; source-first time within 22.0% noise, peak -22.7%, kept -16.9%. All three relevant linearity checks pass. The Windows gate passes: 5838 passed, 68 skipped, 1 xfailed. The user accepts the remaining cold-query and post-query allocation trade-off for merge-then-recover.
@deiteris
deiteris merged commit bb6941f into master Oct 10, 2026
20 checks passed
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