Skip to content

Cherry-pick FCollection from #11366 - #11431

Merged
Agetian merged 3 commits into
Card-Forge:masterfrom
tool4ever:fcoll
Jul 28, 2026
Merged

Cherry-pick FCollection from #11366#11431
Agetian merged 3 commits into
Card-Forge:masterfrom
tool4ever:fcoll

Conversation

@tool4ever

Copy link
Copy Markdown
Contributor

@Hanmac
I looked into just using LinkedHashSet but it's missing too many methods imo.

liamiak1 and others added 3 commits July 27, 2026 22:40
FCollection kept a HashSet beside its list purely to reject duplicate adds
and answer contains() in O(1). Trait rebuilds (getReplacementEffects /
getStaticAbilities / getTriggers, plus every FCollection copy they make)
create tens of millions of these per game, almost all holding one or two
elements and never queried by value - so the set was pure overhead: an extra
allocation per collection and a hash insert per element.

Build the set on demand instead. Until something needs value semantics at
scale (asSet, or growth past a small threshold) uniqueness is enforced by
scanning the list, which is cheaper than the set for the tiny sizes that
dominate. Also copy straight across the backing list when constructing from
another FCollection (the source already guarantees uniqueness) and skip
iterating empty collections in addAll.

Verified against a fixed 5-seed AI-vs-AI match on a 510-card deck: every
game's end state is byte-identical to before, and total match time drops
substantially (the set churn was the single largest allocation source in
the profile).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Agetian
Agetian merged commit 5d9082e into Card-Forge:master Jul 28, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants