Issue #37: Catalog: instrument persistence (append, snapshot stages) and whole-frame update time
- Journal::stats(): last/max append time (encode + write + sync_data), snapshot count, last
snapshot by stage (serialise, write+sync+rename, log reset, bytes, records), slowest
snapshot. Reported by `library.info` → `persistence`; printed per write to stderr under
LIGHTCRAFT_PROFILE.
- UI: `perf.frame_ms` only covers layout (`LightcraftApp::ui`); `logic()` (control channel,
shortcuts, render polling, `persist_if_dirty`) ran untimed. Add `logicMs`, `updateMs`
(logic + layout) and `maxUpdateMs` to `ui.inspect` → perf and a "Frame update" row to
Help ▸ System Info.
- `crates/catalog/examples/persist_bench.rs`: synthetic 1k/10k/85k-photo catalogs (90 % Local
browse records) on FsStore: append latency, compaction at the 2,000-record threshold, load.
Baseline (release, load avg ~240, so absolute times are inflated; median of 3 compactions):
1k photos (3.6 MB snap): append 7 ms, compaction 31 ms (serialise 5, write+sync 12, reset 14)
10k photos (36.5 MB): append 15 ms, compaction 528 ms (serialise 463, write+sync 56)
85k photos (310 MB): append 12 ms, compaction 4.6 s (serialise 2.2-4.4 s, write+sync
0.25-0.8 s); peak RSS 963 MB; load 4.7 s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>