perf(types): компактное представление односложного TypeSet#4188
Conversation
Канонический конструктор TypeSet оборачивал любой набор ссылок в Collections.unmodifiableSet(new LinkedHashSet<>(...)), а LinkedHashSet — это LinkedHashMap с 16-слотовым Node[]-массивом. Для односложных наборов (подавляющее большинство returnType'ов членов) это ~241 байт инфраструктуры коллекции на одну полезную ссылку. Теперь для наборов размера 0 и 1 используется компактное неизменяемое представление (Collections.emptySet / Set.of), без LinkedHashSet и обёртки; для двух и более ссылок сохраняется порядок вставки через LinkedHashSet. Фабрики of() больше не аллоцируют LinkedHashSet дважды для односложного входа. Контракт refs() как Set<TypeRef> и record-семантика equals/hashCode сохранены. Замер на конфигурации nixel2007/cpm (13090 файлов, analyze): кластер LinkedHashSet+LinkedHashMap+Entry+Node[]+UnmodifiableSet (~1.3 ГБ) схлопывается в ImmutableCollections$Set12 (146 МБ); live heap 5.04 ГБ → 4.35 ГБ (-13.7%), давление аллокаций Object[] 74% → 68%. JSON-отчёт побайтно идентичен. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01EWA4hy5YvUBU1CXkdr4npc
📝 WalkthroughWalkthrough
ChangesTypeSet refs normalization
Estimated code review effort🎯 2 (Simple) | ⏱️ ~5 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@src/main/java/com/github/_1c_syntax/bsl/languageserver/types/model/TypeSet.java`:
- Around line 93-94: The TypeSet class has inconsistent null-handling between
the singleton and multi-element code paths: the singleton case using
Set.of(refs[0]) throws NullPointerException on null, while the multi-element
case using LinkedHashSet silently accepts null. Add explicit
Objects.requireNonNull(...) validation in the case 1 branch (for the singleton
path), in the default branch (for the multi-element path), and in the canonical
constructor to ensure consistent null rejection across all TypeSet creation
paths. This will prevent size-dependent behavior and ensure null inputs are
consistently rejected regardless of which factory method or path is used.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: e2b298d7-7409-4b7b-a2b6-6800063ed163
📒 Files selected for processing (1)
src/main/java/com/github/_1c_syntax/bsl/languageserver/types/model/TypeSet.java
|



Что и зачем
TypeSet(returnType членов, типы выражений) — один из самых массовых объектов в системе типов. Канонический конструктор оборачивал любой набор ссылок вCollections.unmodifiableSet(new LinkedHashSet<>(...)), аLinkedHashSetвнутри — этоLinkedHashMap+ 16-слотовыйNode[]-массив. На конфигурации ERP-масштаба это ~6 млн односложныхTypeSet, каждый из которых тратит ~241 байт инфраструктуры коллекции на одну полезную (и без того интернированную)TypeRef.Изменение
Collections.emptySet/Set.of), безLinkedHashSetи обёртки.LinkedHashSet.of()больше не аллоцируютLinkedHashSetдважды для односложного входа.refs() : Set<TypeRef>и record-семантикаequals/hashCodeне меняются.Замер (analyze на
nixel2007/cpm, 13 090 файлов,-Xmx10g)Set12146 МБObject[]allocation pressureJSON-отчёт
analyzeпобайтно идентичен baseline (160 526 263 байт).TypeSetTest— 18/0/0.🤖 Generated with Claude Code
Summary by CodeRabbit