Skip to content

perf(native): share equal model analyses in the native session and guard their CPU - #1073

Closed
kvlonge wants to merge 9 commits into
mainfrom
fix/native-analysis-session-speed
Closed

kvlonge wants to merge 9 commits into
mainfrom
fix/native-analysis-session-speed

Conversation

@kvlonge

@kvlonge kvlonge commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Why

Under native-preview, model analysis took 13.0-13.5s CPU on dense 3,000 models vs ~4.2s for Python. The session analysed every model alone; Python shares one analysis across models whose query differs only in relation names (574 queries vs 2,997).

Changes

  • Session batches share queries as Python's prepare_binding_queries does (stubs, keys, two-member minimum) and re-analyse inexact results alone. Eligibility is never wider than Python's.
  • NativeModelAnalysisSession.sharing reports shared and re-analysed counts.
  • New model_analysis_cpu_ms phase (process CPU), one timer shared with wall phases.
  • Ratio tool --compile-arg; CI ratio entry gates model_analysis_cpu_ms at 1.50x Python + 50ms with --select=*.
  • No Python deleted: Python's sharing still serves the python engine.

Changed expectations: model_analysis_cpu_ms in compile JSON timings; new ratio E2E case; parity cases 22/6/2 and 4/0/3 shared/re-analysed/unshared.

Known residuals:

  • If a member's stubbed SQL fails to normalise, native analyses it unshared; Python raises for the whole batch. No realistic trigger.
  • model_analysis_cpu_ms is process-wide, so without --select=* it includes early-lint threads.
  • No test fails if binding_shapes leaves the key: it follows the same relation facts as analysis_shapes, whose removal fails.

Verification

  • Model analysis CPU, dense 3000, same machine, 3 alternating runs: 13.0-13.5s before, 4.8-4.9s after, Python 4.2-4.3s. 8 runs: 1.09-1.145x. Sharing off: 3.17x, fails.
  • Sabotage: skipping re-analysis or dropping analysis_shapes from the key fails parity.
  • Dense output and diagnostics identical to Python. Differential: 321 identical, analysis-session deferrals unchanged.
  • Compile E2E; cargo test, clippy, fmt (1.99.0); make check-ci; make test (11949 passed); hygiene.

…deserialization

Scalars skip the Expression deserialization that always failed and built a large error per call, and contract evaluation normalizes each type string once per request. Adds contracts_cpu_ms to compile timings and a same-runner python vs native-preview gate on it.
@kvlonge
kvlonge enabled auto-merge October 9, 2026 18:26
@kvlonge
kvlonge disabled auto-merge October 9, 2026 18:26
@kvlonge

kvlonge commented Oct 9, 2026

Copy link
Copy Markdown
Contributor Author

Landed together in #1075 to cut merge-queue CI runs; review history stays here.

@kvlonge kvlonge closed this Oct 9, 2026
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