fix(bench): render contacts in contact-book benchmark - #468
Merged
Mohamed Mansour (mohamedmansour) merged 1 commit intoAug 24, 2026
Merged
Conversation
The contact-book benchmark scaled `contacts`/`filteredContacts` to
10/100/1,000 entries but rendered `RenderOptions::new("index.html", "/")`.
Route selection is request-path driven, so `/` resolved to
`cb-page-dashboard`, which only emits `recentContacts` capped at five. The
scaled arrays were never traversed and output stayed flat at ~24 KB across
all three scales, making the reported throughput meaningless.
Render `/contacts` instead, which resolves to `cb-page-contacts` and loops
the full contact list. Output now scales 34 KB / 252 KB / 2.43 MB.
- Route every render and summary sample through a `REQUEST_PATH` constant.
- Set the fixture `page` field to `contacts` so sidebar state matches the
rendered route.
- Rename the render groups to `contact_book_contacts_render*` so stale
dashboard baselines cannot be compared against the new workload.
- Add a startup guard that renders `CONTACT_COUNTS` in ascending order and
fails unless output strictly increases, so a route regression cannot
silently return.
- Recalibrate the writer pre-allocation constants against the measured
`/contacts` output, and derive the summary writer capacity from the
largest benchmarked scale.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Mohamed Mansour (mohamedmansour)
requested review from
Bang Lee (Qusic),
Akrosh Gandhi (akroshg),
Jane Chu (janechu) and
mcritzjam
and
a lite review from Copilot
August 24, 2026 19:13
Copilot started reviewing on behalf of
Mohamed Mansour (mohamedmansour)
August 24, 2026 19:14
View session
Jane Chu (janechu)
approved these changes
Aug 24, 2026
Mohamed Mansour (mohamedmansour)
deleted the
mohamedmansour-fix-contact-book-bench-route-e68
branch
August 24, 2026 19:16
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes the Rust contact_book_bench workload so it actually benchmarks contact list rendering by rendering the /contacts route (which traverses the full filteredContacts list) instead of / (dashboard, capped at 5 recent contacts). This makes output size and throughput scale with contact count, aligning the benchmark’s intent with the rendered route behavior.
Changes:
- Introduces a single
REQUEST_PATH(/contacts) and threads it through all render sites (bench groups + summary pass). - Updates benchmark fixture state (
page: "contacts") and renames Criterion group IDs to reflect the new workload. - Adds a startup validation guard (
validate_output_scales_with_contacts) plus recalibrates writer capacity constants for the/contactsoutput sizes.
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
crates/webui/benches/contact_book_bench.rsscalescontacts/filteredContactsto 10 / 100 / 1,000 entries, but every render call usedRenderOptions::new("index.html", "/").Route selection is request-path driven — the state
pagefield only controls sidebar highlighting./resolves tocb-page-dashboard, which rendersrecentContactscapped atMAX_RECENT_CONTACTS(5). The scaled arrays were never traversed, so output stayed flat at ~24 KB at every scale and the reported throughput measured nothing about list rendering.Measured on
main(no plugin):/output bytesThe Node addon benchmark already uses
requestPath: "/contacts"; the Rust benchmark had drifted.Fix
Render
/contacts, which resolves tocb-page-contactsand loops the full contact list, emitting onecb-contact-cardper contact with 12 dynamic attributes each./contactsoutput bytesChanges, all in the one benchmark file:
REQUEST_PATHconstant (/contacts) threaded through all sixRenderOptionssites — three benchmark groups plus the summary pass.page→"contacts"so sidebar state matches the rendered route.contact_book_render*→contact_book_contacts_render*, so stale dashboard baselines cannot be compared against the new workload.validate_output_scales_with_contactsrendersCONTACT_COUNTSin ascending order and fails unless output strictly increases. It fails on the old route with an actionable message, so this regression cannot silently return./contactsworkload (see below).Guard proof
Temporarily pointing
REQUEST_PATHat/— the pre-fix behavior — fails immediately:With
/contactsrestored,cargo bench -p microsoft-webui --bench contact_book_bench -- --testpasses.Buffer sizing
The old constants were calibrated for the dashboard route and under-allocated the real workload by 4–5×, forcing repeated reallocation inside the warmup render.
BYTES_PER_CONTACTBYTES_PER_CONTACT_WITH_PLUGINBASE_HTML_BYTESBASE_HTML_BYTES_WITH_PLUGINResulting slack is 0.5–7.6% — enough that no scale reallocates, without retaining excessive memory.
WRITER_HEADROOM(1,024) is unchanged. Rendering is deterministic, so the timed output matches the warmup byte-for-byte; the headroom only absorbs incidental drift and 1 KiB is adequate.SUMMARY_WRITER_CAPACITYwas 64 KiB with a stale comment claiming a ~443 KiB peak. The real peak is ~3.5 MiB. It is now derived fromMAX_CONTACT_COUNT × BYTES_PER_CONTACT_WITH_PLUGIN + BASE_HTML_BYTES_WITH_PLUGIN(aconstblock, no recursion), so it stays in sync ifCONTACT_COUNTSchanges.Validation
New group IDs, now scaling as expected:
cargo xtask check: license-headers, fmt, clippy, deny, test, build, build (wasm), build (examples), and bench (validate) all pass. Thedocsphase fails locally withPROJ-C013: Adapter module graph is incomplete or inconsistent; this reproduces identically on pristinemainwith this change stashed, so it is a pre-existing local baseline failure and is not addressed here.Scope
Benchmark correctness only — one file, no lockfile drift, no product code. This makes no performance claim about the framework; it repairs the workload that later benchmarking work depends on.