From 591718b5e8b1623b9f2b3ddf3e3381e33e65132c Mon Sep 17 00:00:00 2001 From: Frank McSherry Date: Wed, 17 Jun 2026 16:20:39 -0400 Subject: [PATCH] compute: hoist the flat_map decode arena out of the per-row closure `flat_map`/`flat_map_ok` created a fresh `RowArena` inside the per-row logic closure, so a new arena was allocated and dropped for every row processed. Hoist it to the enclosing scope and `clear()` it per row instead, reusing the arena's allocation spine across invocations. This matters more now that the arena is the decode target for compressed arrangement rows (per-column codecs), where each row actually populates it. Addresses post-merge review feedback on #37110. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/compute/src/render/context.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/compute/src/render/context.rs b/src/compute/src/render/context.rs index c7f8388c735b7..1f1367c8a3522 100644 --- a/src/compute/src/render/context.rs +++ b/src/compute/src/render/context.rs @@ -318,14 +318,17 @@ impl<'scope, T: RenderTimestamp> ArrangementFlavor<'scope, T> { + 'static, { let mut datums = DatumVec::new(); + // Reused across invocations: cleared per row rather than reallocated, so the arena's + // allocation spine persists. Declared before the borrow so it outlives any datums that + // decode into it. + let mut temp_storage = RowArena::new(); let logic = move |k: DatumSeq, v: DatumSeq, t, d, ok_session: &mut Session, err_session: &mut Session>| { - // Declared before the borrow so it outlives any datums that decode into it. - let temp_storage = RowArena::new(); + temp_storage.clear(); let mut datums_borrow = datums.borrow(); k.extend_datums(&temp_storage, &mut datums_borrow, Some(max_demand)); let max_demand = max_demand.saturating_sub(datums_borrow.len()); @@ -379,9 +382,12 @@ impl<'scope, T: RenderTimestamp> ArrangementFlavor<'scope, T> { + 'static, { let mut datums = DatumVec::new(); + // Reused across invocations: cleared per row rather than reallocated, so the arena's + // allocation spine persists. Declared before the borrow so it outlives any datums that + // decode into it. + let mut temp_storage = RowArena::new(); let logic = move |k: DatumSeq, v: DatumSeq, t, d, ok_session: &mut Session| { - // Declared before the borrow so it outlives any datums that decode into it. - let temp_storage = RowArena::new(); + temp_storage.clear(); let mut datums_borrow = datums.borrow(); k.extend_datums(&temp_storage, &mut datums_borrow, Some(max_demand)); let max_demand = max_demand.saturating_sub(datums_borrow.len());