perf: round 13 — grouped-view virtualization, notification/login query narrowing, HTTP dedup, locale precompute
Benchmark-gated (BEFORE/AFTER + equivalence/safety gate per change), same discipline as rounds 2-12. Full write-up in benches/ROUND13.md. Shipped: - V1 Grouped views windowed (files route + ResourceList). The grid arm was the last unwindowed path (trash is grouped-by-default in grid): each swimlane now feeds its own VirtualList, outer container a flex stack. vitest gate: 800-item grouped grid mounts <120 .file-item (was 800). - Q1 get_users_by_ids drops the <=512 KiB avatar image + ui_preferences JSONB (notification path never reads them). 30-member fan-out 8.60 -> 0.25 ms (34.3x), ~7.7 MB off the wire. - Q2 Login provisioning is_empty() -> SELECT EXISTS for calendar + address book (every login). 0.193 -> 0.170 ms, widens with owned-row count. - Q3 Recent-access prunes only when the upsert inserted (RETURNING xmax=0) — a re-access can't grow the set. 0.567 -> 0.324 ms (1.75x). - L1 Locale supported-codes precomputed once vs rebuilt per anonymous request. 616 -> 17.3 ns (35.7x), 18 -> 1 allocs. - H1 Duplicate /api TraceLayer removed (global stack already wraps it). 1.86 -> 1.42 us/request, -6 allocs. - H2 client_ip span field: borrow-only ClientIpDisplay vs owned String. 187 -> 173 ns, -1 alloc. Not shipped (discipline): the "media hooks read the blob 3x" lead was a correctness bug, not a perf dup — the raw-path metadata/faces readers resolve only for local+unencrypted+single-chunk blobs and silently produce nothing otherwise. Flagged for maintainers; routing through read_blob_bytes is a correctness fix (perf-neutral-to-negative), not a benchmark-gated perf change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BfidAJD5AHw23jtvBUNamB
This commit is contained in:
@@ -474,18 +474,21 @@ impl DefaultCalendarLifecycleHook {
|
||||
// Ownership-based idempotency check (see hook docstring for
|
||||
// the design rationale). Whether the existing calendar was
|
||||
// auto-provisioned by a prior run, manually created by the
|
||||
// user, or migrated in, we respect it and skip.
|
||||
let existing = self
|
||||
// user, or migrated in, we respect it and skip. `EXISTS`
|
||||
// short-circuits at the first owned row instead of hydrating them
|
||||
// all just to test emptiness — this runs on EVERY login
|
||||
// (benches/ROUND13.md §Q2).
|
||||
let has_calendar = self
|
||||
.calendar_storage
|
||||
.list_calendars_by_owner(user.id())
|
||||
.has_owned_calendar(user.id())
|
||||
.await
|
||||
.map_err(|e| {
|
||||
DomainError::internal_error(
|
||||
"DefaultCalendarHook",
|
||||
format!("list_calendars_by_owner: {e}"),
|
||||
format!("has_owned_calendar: {e}"),
|
||||
)
|
||||
})?;
|
||||
if !existing.is_empty() {
|
||||
if has_calendar {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
||||
@@ -1219,7 +1219,6 @@ impl ContactUseCase for ContactService {
|
||||
|
||||
use crate::application::ports::user_lifecycle::{DeletionMode, LogoutReason, UserLifecycleHook};
|
||||
use crate::domain::entities::user::User;
|
||||
use crate::domain::repositories::address_book_repository::AddressBookRepository;
|
||||
use crate::infrastructure::repositories::pg::AddressBookPgRepository;
|
||||
use async_trait::async_trait;
|
||||
|
||||
@@ -1264,17 +1263,20 @@ impl DefaultAddressBookLifecycleHook {
|
||||
// Ownership-based idempotency check — same rationale as the
|
||||
// calendar hook. Any existing owned address book (auto-
|
||||
// provisioned earlier, user-created, migrated) is respected.
|
||||
let existing = self
|
||||
// `EXISTS` short-circuits instead of hydrating every owned
|
||||
// address book to test emptiness, on EVERY login
|
||||
// (benches/ROUND13.md §Q2).
|
||||
let has_address_book = self
|
||||
.address_book_repo
|
||||
.get_address_books_by_owner(user.id())
|
||||
.has_owned_address_book(user.id())
|
||||
.await
|
||||
.map_err(|e| {
|
||||
DomainError::internal_error(
|
||||
"DefaultAddressBookHook",
|
||||
format!("get_address_books_by_owner: {e}"),
|
||||
format!("has_owned_address_book: {e}"),
|
||||
)
|
||||
})?;
|
||||
if !existing.is_empty() {
|
||||
if has_address_book {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
||||
@@ -98,8 +98,15 @@ impl RecentService {
|
||||
));
|
||||
}
|
||||
|
||||
self.repo.upsert_access(user_id, item_id, item_type).await?;
|
||||
self.repo.prune(user_id, self.max_recent_items).await?;
|
||||
// Prune only when the upsert actually inserted a NEW row — a
|
||||
// re-access refreshes an existing row's timestamp and can never
|
||||
// grow the set past the cap, so the prune (a DELETE over an
|
||||
// OFFSET self-subquery) is a wasted round-trip on that common path
|
||||
// (benches/ROUND13.md §Q3).
|
||||
let inserted = self.repo.upsert_access(user_id, item_id, item_type).await?;
|
||||
if inserted {
|
||||
self.repo.prune(user_id, self.max_recent_items).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user