Reduce index-update preflight cost with typed dependency discovery #42
Labels
No labels
area/cli
area/core
area/database
area/indexing
area/query
type/epic
type/feature
type/foundation
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
JayKobe6k/ClariTree#42
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem and impact
ClariTree's temporally stable
index updatepath parsed and fully indexed every translation unit twice before it could report a no-op or begin semantic analysis. The first pass existed only to discover and fingerprint source dependencies, but it still built the complete owned IR, copied diagnostics, validated it, and retained all per-unit indexing structures. This made update preflight materially slower and more memory-intensive than required, especially for unchanged projects where no analysis or persistence follows.Environment and workload
b9354026f484072e9a7a4d786548045324ec00c09a6556cdf10442197450b37e2424bbecb07c766dmelee-event-matchat6b6f8a8a987c2e871b8b96baa863aaa99e406f33MemorySwapMax=0, explicit memory/time limits, and the same catalog/manifestRepresentative reproduction after creating a baseline revision:
Baseline and profiling evidence
Three comparable 200-TU no-op updates:
b9354029a6556cThe candidate reduced median no-op latency by 32.8% and median peak memory by 43.2%. Every candidate run returned the same no-op revision and persisted counts as the baseline manifest.
One paired 40-TU forced update exercised full parse, semantic analysis, immutable LadybugDB publication, validation, and catalog activation:
b9354029a6556cThe candidate was 9.8% faster end to end. Both revisions persisted exactly 40 translation units, 1,695,601 source facts, 60,796 value definitions, 69,533 value uses, and 146,711 lineage relationships, with identical diagnostics.
Ordinary single-pass full indexing was separately checked for regression: baseline parse-only runs were 24.383/24.845 s and candidate runs were 24.557/25.046 s, with identical definition/use/relationship counts. This is noise-level change rather than an improvement claim.
Root cause
index_compilation_plantwice: baseline stable preflight.LibclangIndexer::indexperforms complete entity collection, source-fact construction, diagnostic conversion, and IR validation: baseline full indexer.The causal mechanism was duplicate full owned-fact construction. The source files must still be parsed twice to enforce the existing temporal-stability guarantee, but the first parse does not need symbols, declarations, references, CFGs, operations, types, diagnostics, or validated IR.
Implemented remediation
Commit
9a6556cdf10442197450b37e2424bbecb07c766d:DiscoveredSourceDependenciesparser-boundary result and default compatibility methods on the source-index ports: typed API, application port.Alternatives considered:
Expected benefit, confidence, and risks
9a6556cdf10442197450b37e2424bbecb07c766d; persisted revisions remain compatible.Acceptance criteria
Related: #9 defines the update behavior; #41 optimizes the persistence work reached by changed updates.
Implemented and pushed in
9a6556cdf1. The 200-TU no-op median improved from 105.802 s to 71.058 s (32.8%) and median peak memory from 507.0 MiB to 288.1 MiB (43.2%). The 40-TU forced-update smoke improved from 67.466 s to 60.854 s with identical diagnostics and all persisted counts. Full required Nix validation passes.JayKobe6k referenced this issue2026-09-12 18:18:27 +00:00