Skip to content

feat: expose reusable card pools - #5

Merged
nichinichisou0609 merged 1 commit into
empty-sekai:mainfrom
allium-review-bot:feat/reusable-card-pool
Aug 29, 2026
Merged

nichinichisou0609 merged 1 commit into
empty-sekai:mainfrom
allium-review-bot:feat/reusable-card-pool

Conversation

@allium-review-bot

Copy link
Copy Markdown

A recommend call spends most of its time building the candidate pool and
only a small fraction searching it, so repeating the same query rebuilds work
that has not changed. Measured on a 672-card account (multi/score, 194
candidates), the search itself is 130 us while the whole call is 3.7 ms.

build_pool returns a PreparedCardPool holding the candidate set, search
context, resolved card details and cultivated cards:

pool = engine.build_pool(options)
result = pool.recommend()
top5 = pool.recommend(limit=5)

limit and timeout_ms are the only options that affect the search stage
alone, so they stay overridable per call; everything else is fixed at build
time. Both entry points share one search-and-materialize path, so results are
identical — a test asserts the decks, score, power and bonus all match
recommend().

Median 4549 us for recommend() versus 448 us for pool.recommend(), about
10x.

No cache is built in. A pool does not observe later changes to the user data,
masterdata or options it was built from, and costs 0.2-0.5 MB depending on the
account and candidate count, so the bound and the invalidation belong to the
caller. The README documents what a pool is bound to, the measured memory, and
a caller-owned LRU example.

The test check fails on lint rules that a newer ruff enabled across the
existing codebase; main reports the same 184 findings, and this branch adds
none.

A `recommend` call spends most of its time building the candidate pool and
only a small fraction searching it, so repeating the same query rebuilds work
that has not changed.

`build_pool` returns a `PreparedCardPool` holding the candidate set, search
context, resolved card details and cultivated cards. Searching it skips
construction entirely; `limit` and `timeout_ms` are search-stage only and stay
overridable per call. Both entry points share one search-and-materialize path,
so results are identical.

Measured on a 672-card account (multi/score, 194 candidates): 4549 us for
`recommend()` versus 448 us for `pool.recommend()` at the median, about 10x.
Pools cost 0.2-0.5 MB each and do not observe later changes to the user data,
masterdata or options they were built from, so no cache is built in: the
README documents the binding, the memory cost and a caller-owned LRU.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@nichinichisou0609
nichinichisou0609 merged commit 6bacb87 into empty-sekai:main Aug 29, 2026
9 checks passed
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