Switch to reserve over extend_from_slice
This is a 0.15% win on diesel.
This commit is contained in:
@@ -39,7 +39,7 @@ pub struct Buffer<T: Copy> {
|
|||||||
data: *mut T,
|
data: *mut T,
|
||||||
len: usize,
|
len: usize,
|
||||||
capacity: usize,
|
capacity: usize,
|
||||||
extend_from_slice: extern "C" fn(Buffer<T>, Slice<'_, T>) -> Buffer<T>,
|
reserve: extern "C" fn(Buffer<T>, usize) -> Buffer<T>,
|
||||||
drop: extern "C" fn(Buffer<T>),
|
drop: extern "C" fn(Buffer<T>),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,32 +79,28 @@ impl<T: Copy> Buffer<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn extend_from_slice(&mut self, xs: &[T]) {
|
pub(super) fn extend_from_slice(&mut self, xs: &[T]) {
|
||||||
// Fast path to avoid going through an FFI call.
|
if xs.len() > self.capacity.wrapping_sub(self.len) {
|
||||||
if let Some(final_len) = self.len.checked_add(xs.len()) {
|
let b = self.take();
|
||||||
if final_len <= self.capacity {
|
*self = (b.reserve)(b, xs.len());
|
||||||
let dst = unsafe { slice::from_raw_parts_mut(self.data, self.capacity) };
|
}
|
||||||
dst[self.len..][..xs.len()].copy_from_slice(xs);
|
unsafe {
|
||||||
self.len = final_len;
|
xs.as_ptr().copy_to_nonoverlapping(self.data.add(self.len), xs.len());
|
||||||
return;
|
self.len += xs.len();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let b = self.take();
|
|
||||||
*self = (b.extend_from_slice)(b, Slice::from(xs));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn push(&mut self, v: T) {
|
pub(super) fn push(&mut self, v: T) {
|
||||||
// Fast path to avoid going through an FFI call.
|
// The code here is taken from Vec::push, and we know that reserve()
|
||||||
if let Some(final_len) = self.len.checked_add(1) {
|
// will panic if we're exceeding isize::MAX bytes and so there's no need
|
||||||
if final_len <= self.capacity {
|
// to check for overflow.
|
||||||
unsafe {
|
if self.len == self.capacity {
|
||||||
*self.data.add(self.len) = v;
|
let b = self.take();
|
||||||
}
|
*self = (b.reserve)(b, 1);
|
||||||
self.len = final_len;
|
}
|
||||||
return;
|
unsafe {
|
||||||
}
|
*self.data.add(self.len) = v;
|
||||||
|
self.len += 1;
|
||||||
}
|
}
|
||||||
let b = self.take();
|
|
||||||
*self = (b.extend_from_slice)(b, Slice::from(std::slice::from_ref(&v)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,9 +142,9 @@ impl<T: Copy> From<Vec<T>> for Buffer<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" fn extend_from_slice<T: Copy>(b: Buffer<T>, xs: Slice<'_, T>) -> Buffer<T> {
|
extern "C" fn reserve<T: Copy>(b: Buffer<T>, additional: usize) -> Buffer<T> {
|
||||||
let mut v = to_vec(b);
|
let mut v = to_vec(b);
|
||||||
v.extend_from_slice(&xs);
|
v.reserve(additional);
|
||||||
Buffer::from(v)
|
Buffer::from(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,6 +152,6 @@ impl<T: Copy> From<Vec<T>> for Buffer<T> {
|
|||||||
mem::drop(to_vec(b));
|
mem::drop(to_vec(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer { data, len, capacity, extend_from_slice, drop }
|
Buffer { data, len, capacity, reserve, drop }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user