]> git.lizzy.rs Git - rust.git/commitdiff
Write primitive types via array buffers
authorMark Rousskov <mark.simulacrum@gmail.com>
Sun, 16 May 2021 01:39:45 +0000 (21:39 -0400)
committerMark Rousskov <mark.simulacrum@gmail.com>
Sat, 29 May 2021 16:52:06 +0000 (12:52 -0400)
This allows a more efficient implementation (avoiding a fallback to memmove,
which is not optimal for short writes).

This saves 0.29% on diesel.

library/proc_macro/src/bridge/buffer.rs
library/proc_macro/src/bridge/rpc.rs

index a2030b9b8bffef2982fc3e6a1dd2fb55e6128624..717201aef102bf60a78b61837adca7d8961f7e25 100644 (file)
@@ -78,8 +78,23 @@ pub(super) fn take(&mut self) -> Self {
         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());
         }
index ee9a2cf9a9709e3a1fe81815229b2a0ea0bde789..588e6ded0f48068f937b697b1d206ab3f5046113 100644 (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());
             }
         }