Skip to content

perf(references): индекс вхождений по строке для O(1) getReference#4249

Merged
nixel2007 merged 1 commit into
developfrom
claude/perf-reference-occurrence-line-index
Jul 10, 2026
Merged

perf(references): индекс вхождений по строке для O(1) getReference#4249
nixel2007 merged 1 commit into
developfrom
claude/perf-reference-occurrence-line-index

Conversation

@nixel2007

@nixel2007 nixel2007 commented Jul 9, 2026

Copy link
Copy Markdown
Member

Описание

ReferenceIndex.getReference(uri, position) — фундамент всей резолюции ссылок (definition / references / rename / hover / инференс типов). Это первый ReferenceFinder в цепочке, вызывается на каждый findReference.

Что было: линейный скан всего набора вхождений документа с Ranges.containsPosition на каждом:

locationRepository.getSymbolOccurrencesByLocationUri(uri)   // Set всех вхождений (каждый вызов метода,
  .filter(occ -> containsPosition(occ.location, position))  // использование переменной, ссылка на модуль)
  .findAny();                                                // — десятки тысяч в крупном модуле

То есть O(вхождений) на вызов → на большом файле резолюция становится квадратичной.

Что стало: в LocationRepository добавлен вторичный индекс locationsByLine (URI → строка → Set<SymbolOccurrence>), наполняемый в updateLocation и очищаемый в delete (тот же жизненный цикл, что и у основного набора — новых событий не требуется). Метод findByPosition делает O(1)-lookup по строке и разводит несколько вхождений на одной строке по колонкам через тот же Ranges.containsPosition. getReference делегирует в него.

Диапазоны вхождений непересекающиеся, поэтому парити с прежним findAny сохраняется (совпадение максимум одно).

Зачем

По CPU-профилю (JFR) на большом реальном модуле getReference — доминанта: ~77% времени диагностики UnknownMember и, через инференс/резолв, значимая доля всей резолюции ссылок на больших файлах. Это линейный скан, устранимый индексом.

Замеры

Нагрузка — UnknownMember по общему модулю УправлениеДоступомСлужебный из SSL (~48k строк); чистый A/B в одной JVM, переключается только реализация lookup:

  • Время: линейный скан 21 394 мс → line-индекс 3 927 мс = ×5.45 (−81.6%), число срабатываний неизменно (6540 = 6540).
  • Память (изолированно, замер used-heap до/после сброса только вторичного индекса): footprint ≈ 4.9 MB на 29 552 вхождения (≈174 байт/вхождение, 18 655 line-бакетов).

Ускоряет любую резолюцию ссылок с попаданием в индекс, не только UnknownMember.

Связанные задачи

Closes

Чеклист

Общие

  • Ветка PR обновлена из develop (ветка создана от актуального develop)
  • Отладочные, закомментированные и прочие, не имеющие смысла участки кода удалены
  • Изменения покрыты тестами (LocationRepositoryTest: парити со сканом, несколько вхождений на строке по колонкам, инвалидация delete)
  • Обязательные действия перед коммитом выполнены (gradlew precommit) — прогнаны затронутые тесты references/definition/rename/hover/инференс/инкрементальных изменений; полный precommit за мейнтейнерами

Дополнительно

Часть серии независимых перф-правок, снятых по цепочке CPU-профилей одной диагностики на большом файле. Другие PR серии: индекс объявлений символов, мемоизация инференса выражений, резолв членов по терминалу.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BSiRGLm633B4EmvG3vkk4V


Generated by Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved reference lookup accuracy for symbols at specific cursor positions, including cases where multiple matches appear on the same line.
    • Reference results now stay consistent after entries are removed.
  • Performance
    • Speeded up position-based reference searches, reducing unnecessary scanning during lookup.
  • Tests
    • Added coverage for exact-position matching, same-line disambiguation, and post-deletion behavior.

ReferenceIndex.getReference(uri, position) — фундамент всей резолюции ссылок
(finder #40, идёт первым на каждый findReference) — линейно сканировал весь
набор вхождений документа (каждый вызов метода, использование переменной,
ссылка на модуль — десятки тысяч в крупном модуле) с containsPosition на
каждом. По JFR это доминанта UnknownMember (~77%), а через инференс/резолв —
и всей резолюции по большим файлам.

В LocationRepository добавлен вторичный индекс locationsByLine
(URI -> строка -> Set вхождений), наполняемый в updateLocation и чистящийся
в delete (тот же жизненный цикл, что у основного набора; новых событий не
надо). findByPosition делает O(1)-lookup по строке и разводит несколько
вхождений на строке по колонкам через тот же Ranges.containsPosition.
Диапазоны вхождений непересекающиеся, поэтому парити с прежним findAny
сохраняется (совпадение максимум одно). getReference делегирует в него.

Замеры (UnknownMember по SSL УправлениеДоступомСлужебный, ~48k строк;
чистый A/B в одной JVM, переключается только lookup):
- время: линейный скан 21394 -> line-индекс 3927 мс (×5.45, −81.6%),
  срабатываний неизменно (6540);
- память (изолированно, до/после сброса вторичного индекса): footprint
  ≈ 4.9 MB на 29552 вхождения (~174 байт/вхождение).

Ускоряет любую резолюцию ссылок с попаданием в индекс (definition/
references/rename/hover/инференс), не только UnknownMember. Поведение
сохранено — тесты references/definition/rename/hover/инференс/
инкрементальных изменений зелёные.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01BSiRGLm633B4EmvG3vkk4V
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8c5984f6-d3c0-42ac-9d32-6d9b439be410

📥 Commits

Reviewing files that changed from the base of the PR and between 164fd7f and 9a3eb5a.

📒 Files selected for processing (4)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/references/CLAUDE.md
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/references/ReferenceIndex.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/references/model/LocationRepository.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/references/model/LocationRepositoryTest.java

📝 Walkthrough

Walkthrough

LocationRepository now maintains a line-based occurrence index for position lookups. ReferenceIndex delegates matching to this index, while new tests verify matching, same-line disambiguation, negative cases, and deletion behavior.

Changes

Reference lookup

Layer / File(s) Summary
Line-indexed location repository
src/main/java/.../references/model/LocationRepository.java, src/main/java/.../references/CLAUDE.md
Adds a URI-to-line occurrence index, position matching through the indexed line, update/delete maintenance, and corresponding documentation.
ReferenceIndex position integration
src/main/java/.../references/ReferenceIndex.java
Routes position-based reference lookup through LocationRepository.findByPosition.
Position lookup validation
src/test/java/.../references/model/LocationRepositoryTest.java
Tests linear-scan equivalence, same-line disambiguation, empty results, and index cleanup after deletion.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title clearly summarizes the performance change: a line-based occurrence index for faster getReference lookup.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/perf-reference-occurrence-line-index

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sonarqubecloud

sonarqubecloud Bot commented Jul 9, 2026

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Test Results

 3 594 files   3 594 suites   1h 42m 19s ⏱️
 3 560 tests  3 542 ✅  18 💤 0 ❌
21 360 runs  21 248 ✅ 112 💤 0 ❌

Results for commit 9a3eb5a.

♻️ This comment has been updated with latest results.

@nixel2007
nixel2007 merged commit 980a604 into develop Jul 10, 2026
42 checks passed
@nixel2007
nixel2007 deleted the claude/perf-reference-occurrence-line-index branch July 10, 2026 06:18
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.

2 participants