Skip to content

Commit 9db9384

Browse files
committed
perf: fast-path inline strings in ByteViewGroupValueBuilder::vectorized_append
When the input StringView/BinaryView array has no data buffers (all values ≤12 bytes, stored inline), skip the value() → make_view() round-trip in do_append_val_inner and instead copy the u128 views directly. Arrow guarantees valid arrays have zero-padded inline views, so the direct copy is semantically identical and lets the compiler vectorize the loop. Also pre-reserve views capacity in the slow path (non-inline strings) to avoid repeated Vec reallocation. Closes #21568
1 parent c17c87c commit 9db9384

1 file changed

Lines changed: 12 additions & 2 deletions

File tree

  • datafusion/physical-plan/src/aggregates/group_values/multi_group_by

datafusion/physical-plan/src/aggregates/group_values/multi_group_by/bytes_view.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,18 @@ impl<B: ByteViewType> ByteViewGroupValueBuilder<B> {
166166

167167
Nulls::None => {
168168
self.nulls.append_n(rows.len(), false);
169-
for &row in rows {
170-
self.do_append_val_inner(arr, row);
169+
if arr.data_buffers().is_empty() {
170+
// Fast path: all strings are inline (≤12 bytes).
171+
// The input array's u128 views are already in the correct format;
172+
// copy them directly instead of going through value() → make_view().
173+
self.views.extend(rows.iter().map(|&row| arr.views()[row]));
174+
} else {
175+
// Slow path: some strings are non-inline (>12 bytes).
176+
// Pre-reserve views capacity to avoid repeated reallocation.
177+
self.views.reserve(rows.len());
178+
for &row in rows {
179+
self.do_append_val_inner(arr, row);
180+
}
171181
}
172182
}
173183

0 commit comments

Comments
 (0)