perf: round 18 — calendar-event in-place iCal edit, ResourceList incremental id-index

Two items from the ROUND17 deferred list, each benchmark-gated with a
BEFORE/AFTER equivalence gate and a rollback-on-regression check (ROUND2–17
discipline). See benches/ROUND18.md.

[C1] backend — CalendarEvent::update_ical_property / remove_ical_property
rewrote the ENTIRE ical_data body with format!("{}{}{}") on every call and
allocated two search needles per call. calendar_storage_adapter::update_event
fans a multi-field edit out into one call per changed field, so a full REST
edit paid one full-body (up to ~11 KB) allocation per property. The body is
now mutated in place (replace_range for an existing property, four insert/
insert_str for a new one, byte-identical spans) and the single "\nNAME:"
needle is built on the stack (the "\r\nNAME:" needle was redundant — the LF
form is its suffix). bench_round18_micro [C1]: 70 -> 2 allocs/op (68 fewer),
2.46x wall, emitted body byte-identical.

[F1] frontend — ResourceList itemIndexById rebuilt a fresh Map over the whole
accumulated list every infinite-scroll page (O(N)/page, O(N^2) drain) and,
being a new instance each page, re-fired the reap-stale effect (another O(N)
id Set/page). New ItemIndexBuilder extends a persistent Map with the fresh
page only and reuses the reference across appends; the reap-stale effect now
tests membership against it. round18.bench.test.ts [F1]: 40x50 drain 74.1 ->
6.4 ms (11.5x), deep-equal to the reference at every page, reference-contract
gate (same-ref append / new-ref rebuild).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FoxFtikahM1N4PE5s3ZVH3
This commit is contained in:
Claude
2026-07-19 20:53:30 +00:00
parent ba2245a524
commit 6bc09cb3b3
7 changed files with 837 additions and 53 deletions
+13
View File
@@ -354,6 +354,19 @@ name = "bench_micro_allocs"
path = "examples/bench_micro_allocs.rs"
required-features = ["bench"]
# Round-18 battery ────────────────────────────────────────────────────────────
# Round-18 calendar-event edit CPU/alloc micro-pack — `update_ical_property` /
# `remove_ical_property` mutate the `ical_data` body in place (`replace_range` /
# `insert`) instead of re-`format!`ing the whole body per changed property, and
# build the single `\nNAME:` search needle on the stack (dropping the redundant
# `\r\nNAME:` needle). A multi-field REST edit went from one full-body (up to
# ~11 KB) allocation per property to none. No Postgres.
[[example]]
name = "bench_round18_micro"
path = "examples/bench_round18_micro.rs"
required-features = ["bench"]
# Round-17 battery ────────────────────────────────────────────────────────────
# Round-17 dedup + CardDAV CPU/alloc micro-pack — `hash_chunk_sequence` by-value