Skip to content

Commit 8a7f747

Browse files
committed
More messing around with vectorization
1 parent 2cdb0fe commit 8a7f747

File tree

1 file changed

+33
-9
lines changed

1 file changed

+33
-9
lines changed

arrow-buffer/src/buffer/mutable.rs

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,7 @@ impl MutableBuffer {
721721
/// # Safety
722722
/// This method assumes that the iterator's size is correct and is undefined behavior
723723
/// to use it on an iterator that reports an incorrect length.
724+
#[inline]
724725
pub unsafe fn extend_from_trusted_len_iter<T: ArrowNativeType, I: Iterator<Item = T>>(
725726
&mut self,
726727
iterator: I,
@@ -731,19 +732,42 @@ impl MutableBuffer {
731732
let len = upper * item_size;
732733
self.reserve(len);
733734

734-
let mut dst = self.data.as_ptr();
735+
let written = unsafe {
736+
let dst = self.data.as_ptr().add(self.len);
737+
self.extend_from_trusted_len_iter_inner(iterator, dst)
738+
};
739+
assert_eq!(written as usize, len, "Trusted iterator length was not accurately reported");
740+
self.len += len;
741+
}
742+
743+
/// Copies the contents of a trusted-length iterator into the provided destination pointer.
744+
/// returning the number of bytes written.
745+
///
746+
/// This is its own non inlined function to maximize the chances of
747+
/// maximally vectorizing the inner loop.
748+
///
749+
/// # Safety
750+
/// The caller must ensure that `dst` points to a memory region large enough to hold
751+
/// all items from the iterator.
752+
#[inline(never)]
753+
pub unsafe fn extend_from_trusted_len_iter_inner<T: ArrowNativeType, I: Iterator<Item = T>>(
754+
&mut self,
755+
iterator: I,
756+
mut dst: *mut u8,
757+
) -> isize
758+
{
759+
let item_size = std::mem::size_of::<T>();
760+
let start = dst;
735761
for item in iterator {
736762
// note how there is no reserve here (compared with `extend_from_iter`)
737763
let src = item.to_byte_slice().as_ptr();
738-
unsafe { std::ptr::copy_nonoverlapping(src, dst, item_size) };
739-
dst = unsafe { dst.add(item_size) };
764+
unsafe {
765+
std::ptr::copy_nonoverlapping(src, dst, item_size);
766+
dst = dst.add(item_size)
767+
};
740768
}
741-
assert_eq!(
742-
unsafe { dst.offset_from(self.data.as_ptr()) } as usize,
743-
len,
744-
"Trusted iterator length was not accurately reported"
745-
);
746-
self.len += len;
769+
unsafe { dst.offset_from(start) }
770+
747771
}
748772

749773
/// Creates a [`MutableBuffer`] from an [`Iterator`] with a trusted (upper) length.

0 commit comments

Comments
 (0)