Write primitive types via array buffers

This allows a more efficient implementation (avoiding a fallback to memmove,
which is not optimal for short writes).

This saves 0.29% on diesel.
This commit is contained in:
Mark Rousskov 2021-05-15 21:39:45 -04:00
parent 92b2894d31
commit 8c2080886f
2 changed files with 17 additions and 2 deletions

View File

@ -78,8 +78,23 @@ impl<T: Copy> Buffer<T> {
mem::take(self)
}
// We have the array method separate from extending from a slice. This is
// because in the case of small arrays, codegen can be more efficient
// (avoiding a memmove call). With extend_from_slice, LLVM at least
// currently is not able to make that optimization.
pub(super) fn extend_from_array<const N: usize>(&mut self, xs: &[T; N]) {
if xs.len() > (self.capacity - self.len) {
let b = self.take();
*self = (b.reserve)(b, xs.len());
}
unsafe {
xs.as_ptr().copy_to_nonoverlapping(self.data.add(self.len), xs.len());
self.len += xs.len();
}
}
pub(super) fn extend_from_slice(&mut self, xs: &[T]) {
if xs.len() > self.capacity.wrapping_sub(self.len) {
if xs.len() > (self.capacity - self.len) {
let b = self.take();
*self = (b.reserve)(b, xs.len());
}

View File

@ -27,7 +27,7 @@ macro_rules! rpc_encode_decode {
(le $ty:ty) => {
impl<S> Encode<S> for $ty {
fn encode(self, w: &mut Writer, _: &mut S) {
w.write_all(&self.to_le_bytes()).unwrap();
w.extend_from_array(&self.to_le_bytes());
}
}