perf(lsp): index C++ short-name type lookups - #1679
Conversation
Avoid repeated full type-registry scans in the namespaced-type fallback. Build the optional index only for C/C++ cross registries while preserving candidate order, post-finalize tails, and allocation fallback. Refs DeusData#1677 Signed-off-by: astandrik <astandrik@yandex-team.ru>
|
Thanks for opening this — it has been seen, and it is queued. This note is automated, but it is not a brush-off: it exists so you know where your PR stands instead of having to guess from silence. Current review status: working through a backlog. What that means for this PR, concretely:
Things that will genuinely speed it up whenever review does happen:
If this fixes a bug, a reproduction we can run is worth more than a description of the symptom. Thanks for contributing, and sorry in advance for the wait. |
There was a problem hiding this comment.
Pull request overview
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Adds an opt-in short-name index for C/C++ type registry lookups to avoid full type scans during namespaced-type fallback, improving cross-file resolution performance (Fixes #1677).
Changes:
- Introduces an optional “final qualified-name segment” index in the shared type registry and a new iterator API to traverse candidates in registry order.
- Switches C-LSP member lookup fallback from full-registry scan to indexed iteration and builds the index in C/C++ cross-registry paths.
- Expands the C-LSP test suite to differentially verify iterator ordering, tail behavior, and fallback-to-linear semantics.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| tests/test_c_lsp.c | Extends tests to validate the new short-name type iterator ordering, collisions workload, tail scan, and fallback behavior. |
| internal/cbm/lsp/type_registry.h | Adds registry fields + APIs for the optional type short-name index and iterator contract. |
| internal/cbm/lsp/type_registry.c | Implements index build + iterator for “types by short name”, with tail scanning fallback behavior. |
| internal/cbm/lsp/c_lsp.c | Uses the new iterator in c_lookup_member_depth and builds the index after finalize in cross-registry paths. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Signed-off-by: astandrik <astandrik@yandex-team.ru>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (1)
tests/test_c_lsp.c:15444
- This tail assertion again treats the hash-prefilter iterator as an exact-match iterator. A hash-equivalent non-
Traitcandidate from the finalized chain would be returned before these expected indices, even though production correctly filters it. Please apply the same final-segment check used by the earlier assertions before validating the tail order.
ASSERT_EQ(cbm_type_name_iter_next(&nit), 0);
ASSERT_EQ(cbm_type_name_iter_next(&nit), 4);
ASSERT_EQ(cbm_type_name_iter_next(&nit), 5);
ASSERT_EQ(cbm_type_name_iter_next(&nit), tail_type_i);
ASSERT_EQ(cbm_type_name_iter_next(&nit), -1);
What does this PR do?
Fixes #1677.
The C/C++ namespaced-type fallback currently scans every registered type whenever direct, module-prefixed, alias, and base-class lookup miss. On the public YDB corpus this dominated cross-file resolution.
This PR adds an optional final-qualified-name-segment index to the shared type registry and explicitly builds it in the two C/C++ cross-LSP registry paths.
c_lookup_member_depthwalks the indexed candidate chain instead of the full registry while retaining the existing exact dotted-suffix check, duplicate exclusion, ascending candidate order, and current-module preference.The primitive is reusable but the rollout is intentionally scoped:
O(type_count)construction scan or allocation; they only carry the constant common-registry metadata fields.Benchmark
Fast mode, 18 workers, fresh isolated caches, public
ydb-platform/ydbcommitbe88c989a45f90ea7b2372cb0f9098e0fa23a3d9:parallel_resolveThat is 2.63-2.72x faster end to end and 6.50-6.88x faster in resolution, depending on the baseline. All compared runs retained the same 106,939 input file hashes and coverage counts. Peak RSS varied between runs, so this PR makes no memory-improvement claim.
Full graph identity is order-sensitive in this pipeline: the two byte-identical baselines themselves changed 222,076 common node payloads and tens of thousands of symmetric edge identities. The direct semantic gate is therefore a differential iterator test against the former linear scan, supplemented by the observed baseline-to-baseline drift envelope. Full reproduction details are in #1677.
Why this is safe
Verification
760 passed, 0 failedwith-Werror.7,491 passed, 0 failed, 5 skippedacross 138 suites; the repository no-skips contract gate passed.--versionsmoke passed.git diff --checkpassed.Local verification now includes the canonical clean ASan+UBSan venue leg and repository
lint-ciwith cppcheck 2.21; both pass. The current PR-head CI run is still in progress.Checklist
git commit -s) — required, CI rejectsunsigned commits (DCO, see CONTRIBUTING.md)
scripts/test.sh) — canonical clean ASan+UBSan venue leg passesmake -f Makefile.cbm lint-ci) — cppcheck, clang-format, and no-suppression gates pass