Profiled off the player's own 2026-10-18 session log, where one blocked frame
ran 7,725 ms: the file loading is 4,505 ms of it (pfQuest's `init\data.xml`
alone 695 ms, pfQuest-octo's 311 ms, all of FrameXML 693 ms), then
`load_icon_catalog` 396 ms, the random-property table 259 ms, and the first
VM tick the remaining ~2.3 s.
This takes the icon catalog. It walked `Chain::list()`, and the walk is what
the catalog costs — the module says so itself: classifying the three buckets
out of the names is 1.4 ms. Per name a full list allocates a normalized dedup
key, hashes it into a 102k-entry set, resolves the winning archive and asks it
for a size; the prefix this caller wants was tested *after* all of that, on
every name in the chain.
So `Chain::list_under(prefix)` tests it first, with the same case-insensitive,
separator-blind compare the caller was doing for itself. Measured on this
install, and the test prints the pair it quotes: 102,144 entries in 471 ms
listed whole against 51 ms for the 3,205 under `Interface\Icons\`, the same
entries and the same sizes either way. 420 ms off every login, and off every
`/reload`, which rebuilds the catalog for the new VM.
Nothing else in the client lists the chain; `benilla-extract` does and wants
the lot, so `list()` keeps its name and its body, now shared.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SgstFWtn1RxEJ5kVrpgYwn