Skip to content

Commit 46fcb0c

Browse files
authored
Speed up checked kernels for non-null data (~1.4-5x faster) (#2749)
* Speed up checked kernels * Fast path for non-null * Move some code
1 parent ca00b67 commit 46fcb0c

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

arrow/src/compute/kernels/arity.rs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,26 @@ where
106106
let len = array.len();
107107
let null_count = array.null_count();
108108

109-
let mut buffer = BufferBuilder::<O::Native>::new(len);
110-
buffer.append_n_zeroed(array.len());
111-
let slice = buffer.as_slice_mut();
109+
if null_count == 0 {
110+
let values = array.values().iter().map(|v| op(*v));
111+
// JUSTIFICATION
112+
// Benefit
113+
// ~60% speedup
114+
// Soundness
115+
// `values` is an iterator with a known size because arrays are sized.
116+
let buffer = unsafe { Buffer::try_from_trusted_len_iter(values)? };
117+
return Ok(unsafe { build_primitive_array(len, buffer, 0, None) });
118+
}
112119

113120
let null_buffer = array
114121
.data_ref()
115122
.null_buffer()
116123
.map(|b| b.bit_slice(array.offset(), array.len()));
117124

125+
let mut buffer = BufferBuilder::<O::Native>::new(len);
126+
buffer.append_n_zeroed(array.len());
127+
let slice = buffer.as_slice_mut();
128+
118129
try_for_each_valid_idx(array.len(), 0, null_count, null_buffer.as_deref(), |idx| {
119130
unsafe { *slice.get_unchecked_mut(idx) = op(array.value_unchecked(idx))? };
120131
Ok::<_, ArrowError>(())
@@ -284,9 +295,21 @@ where
284295
if a.is_empty() {
285296
return Ok(PrimitiveArray::from(ArrayData::new_empty(&O::DATA_TYPE)));
286297
}
287-
288298
let len = a.len();
299+
300+
if a.null_count() == 0 && b.null_count() == 0 {
301+
let values = a.values().iter().zip(b.values()).map(|(l, r)| op(*l, *r));
302+
let buffer = unsafe { Buffer::try_from_trusted_len_iter(values) }?;
303+
// JUSTIFICATION
304+
// Benefit
305+
// ~75% speedup
306+
// Soundness
307+
// `values` is an iterator with a known size from a PrimitiveArray
308+
return Ok(unsafe { build_primitive_array(len, buffer, 0, None) });
309+
}
310+
289311
let null_buffer = combine_option_bitmap(&[a.data(), b.data()], len).unwrap();
312+
290313
let null_count = null_buffer
291314
.as_ref()
292315
.map(|x| len - x.count_set_bits())

0 commit comments

Comments
 (0)