Skip to content

typing/perf 2/5: warm-path foundation — hygiene + schema-lifetime refine cache - #82

Open
Felipe705x wants to merge 2 commits into
tc-perf/01-instrumentationfrom
tc-perf/03-refine-cache
Open

typing/perf 2/5: warm-path foundation — hygiene + schema-lifetime refine cache#82
Felipe705x wants to merge 2 commits into
tc-perf/01-instrumentationfrom
tc-perf/03-refine-cache

Conversation

@Felipe705x

@Felipe705x Felipe705x commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #80. Consolidates former #81 (hygiene) + #82 (refine cache) — two commits.

  • Hygiene (measured as noise, kept as risk-free cleanup): in-place single-MATCH check, iterator keys(), Rc-shared env merges, one fewer clone per subquery.
  • Refine memo cache on Schema: the linear-scan-with-allocating-meets in VariableType::refine memoizes per input type; Rc-shared across Schema::clone → transparently cross-query for REPL/Connection lifetimes; invalidation by construction (DDL/inference replace the Schema). Kill switch GQLITE_DISABLE_TC_REFINE_CACHE; differential suite tests/tc_refine_cache_test.rs.

Measured: 15–35% on labeled shapes at steady state (100% hit rate); chain_dir's small gain isolated descriptor/PathType meets as the next term → PR 3/5.

🤖 Generated with Claude Code

Felipe705x and others added 2 commits July 22, 2026 22:57
…ones

- check_query: a single non-optional MATCH is checked in place instead
  of through collapsed_pattern(), which for one match is exactly "deep-
  clone the whole pattern AST". Multi-match keeps the Join collapse.
- TypeEnvironment::keys() returns an iterator (no Vec per call); new
  iter()/set_shared() let env merges share Rc bindings instead of
  deep-cloning descriptor trees (the Filter ambient merge did one deep
  clone per binding).
- warn_for_collapsed_bindings iterates bindings directly (no key Vec,
  no double hash lookups).
- check_subquery_body seeds its fold from the outer env directly —
  one up-front clone (the ambient push) instead of two per subquery.

Measured effect (pattern_typecheck, LDBC SF0.1 schema): within noise
on every category (chain_16 448 → 436 us, subq_exists 69.1 → 68.4 us)
— claimed as hygiene, not as a win. The schema-scan term dominates;
that is QW3/QW4 territory.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…apes)

VariableType::refine's Node/Edge arms — a linear scan of the schema with
recursive is_subtype + allocating meet per entry — now memoize per input
type in a HashMap attached to the Schema (Rc-shared, RefCell). Because
Typechecker::new(schema.clone()) shares the Rc, the cache is
transparently cross-query for REPL/Connection lifetimes; invalidation is
by construction (DDL and inference replace the whole Schema, never
mutate in place; serde skips the field so deserialized schemas start
cold). Capped at 4096 entries as a safety valve.

- Hash derives on VariableType / DescriptorType / PropertyType (LabelType
  and SimpleType already had them) to key the memo.
- Kill switch GQLITE_DISABLE_TC_REFINE_CACHE=1 (read per call, same
  convention as the runtime toggles) for A/B.
- New refine_cache_hits counter in typing::stats + CSV/stdout columns in
  pattern_typecheck.
- tests/tc_refine_cache_test.rs: differential suite pinning cache-on
  (cold AND warm) ≡ cache-off verdicts/errors/warnings over star and
  movies.gdb-inferred schemas.

Measured (pattern_typecheck, LDBC SF0.1 schema, steady state = 100%
hit rate on every case):
- chain_16   436 → 349 us (−20%)   anydir_8  194 → 148 us (−24%)
- union_8    174 → 140 us (−20%)   repeat_1_3 21.5 → 13.7 us (−36%)
- subq_exists 68 → 58 us (−15%)    chain_dir_16 440 → 423 us (−4%)
- anon_unlabeled unchanged (its cost is PathType tree growth, not refine)

chain_dir's small gain isolates the next dominant term for labeled
shapes: PathType/descriptor meets (pt_meets 112 vs chain's 48).

Consequence for the planned QW4 (schema label index): gated OUT. At
steady state the cache already answers every scan-arm call; the index
could only accelerate the one cold scan per distinct descriptor per
session (~10 us each on 25 edge entries). Recorded in the final report
instead of implemented.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Felipe705x Felipe705x changed the title typing/perf 3/4: refine memo cache on Schema (15–35% on labeled shapes) typing/perf 2/5: warm-path foundation — hygiene + schema-lifetime refine cache Aug 29, 2026
@Felipe705x
Felipe705x changed the base branch from tc-perf/02-hygiene to tc-perf/01-instrumentation August 29, 2026 21:07
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