perf(references): индекс вхождений по строке для O(1) getReference#4249
Conversation
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
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthrough
ChangesReference lookup
Estimated code review effort: 3 (Moderate) | ~20 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
Test Results 3 594 files 3 594 suites 1h 42m 19s ⏱️ Results for commit 9a3eb5a. ♻️ This comment has been updated with latest results. |



Описание
ReferenceIndex.getReference(uri, position)— фундамент всей резолюции ссылок (definition / references / rename / hover / инференс типов). Это первыйReferenceFinderв цепочке, вызывается на каждыйfindReference.Что было: линейный скан всего набора вхождений документа с
Ranges.containsPositionна каждом:То есть 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:Ускоряет любую резолюцию ссылок с попаданием в индекс, не только
UnknownMember.Связанные задачи
Closes
Чеклист
Общие
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