perf(mesh): memoise the whole-container decode

Filtering after the assignment made every subset query a full decode (~15s on a
50MB container). full_decode_cached memoises it per container -- fingerprint is
length plus three sampled 4KB windows, keyed with min_consistency, last four kept.
Decoding five ships from Stage_S02 in turn: 10.5s for the first, then 48us-1.4ms.
A stage now costs one decode rather than one per ship. Ten suites green, viewer
builds, and a spot-checked resource still lands on the same offset.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-12 18:57:50 +00:00
parent c79c0f6ccf
commit 33a7bf836b
3 changed files with 104 additions and 5 deletions

View File

@@ -1113,11 +1113,24 @@ always runs over the whole container, and a subset is now a subset of the
container's own answer. Verified: one-name, three-name and full decodes now
return the identical offset for the same resource.
**Cost, stated plainly:** a single-resource query on a 50 MB container went from
near-instant to **~15 s**, because it now anchors every resource. The viewer
calls this once per ship view (with cancellation), so it is a slow prepare step
rather than a per-frame cost — but caching the per-container decode is the
obvious follow-up and is not done here.
**Cost, and the cache that pays it back.** Because the assignment must see every
resource, a single-resource query became as expensive as a full decode (~15 s on
a 50 MB container). `full_decode_cached` memoises the whole-container decode,
keyed by a fingerprint of the bytes (length + three sampled 4 KB windows) and the
consistency setting, holding the last four containers. Decoding five ships from
`Stage_S02` in turn, as the viewer does:
```
e007: 2 models in 10.494 s ← the one full decode
e010: 2 models in 48.6 µs
e105: 37 models in 1.42 ms
e106: 32 models in 92.7 µs
e108: 13 models in 73.7 µs
```
So a stage costs one decode, not one per ship. The whole-container path
(`anchor_models_cancellable`, what the sweeps use) stays uncached — it is already
the thing being measured.
### The consistency figure is mostly bounding boxes — real disagreement is ONE resource