about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMark Rousskov <mark.simulacrum@gmail.com>2021-05-15 18:54:57 -0400
committerMark Rousskov <mark.simulacrum@gmail.com>2021-05-29 12:45:07 -0400
commit299ac7589410a4e9541d0483161abb9e455e0ec1 (patch)
tree5725b24abd6a332ea3f575fd861c12b023b1f4c0
parent9f75dbfa69ba8508fa7765305f75cd96dff06078 (diff)
downloadrust-299ac7589410a4e9541d0483161abb9e455e0ec1.tar.gz
rust-299ac7589410a4e9541d0483161abb9e455e0ec1.zip
Specialize single-element writes to buffer
copy_from_slice generally falls back to memcpy/memmove, which is much more expensive
than we need to write a single element in.

This saves 0.26% instructions on the diesel benchmark.
-rw-r--r--library/proc_macro/src/bridge/buffer.rs15
-rw-r--r--library/proc_macro/src/bridge/rpc.rs2
2 files changed, 16 insertions, 1 deletions
diff --git a/library/proc_macro/src/bridge/buffer.rs b/library/proc_macro/src/bridge/buffer.rs
index aeecbd49662..26d210a01c5 100644
--- a/library/proc_macro/src/bridge/buffer.rs
+++ b/library/proc_macro/src/bridge/buffer.rs
@@ -91,6 +91,21 @@ impl<T: Copy> Buffer<T> {
         let b = self.take();
         *self = (b.extend_from_slice)(b, Slice::from(xs));
     }
+
+    pub(super) fn push(&mut self, v: T) {
+        // Fast path to avoid going through an FFI call.
+        if let Some(final_len) = self.len.checked_add(1) {
+            if final_len <= self.capacity {
+                unsafe {
+                    *self.data.add(self.len) = v;
+                }
+                self.len = final_len;
+                return;
+            }
+        }
+        let b = self.take();
+        *self = (b.extend_from_slice)(b, Slice::from(std::slice::from_ref(&v)));
+    }
 }
 
 impl Write for Buffer<u8> {
diff --git a/library/proc_macro/src/bridge/rpc.rs b/library/proc_macro/src/bridge/rpc.rs
index 5c2f9ec9848..ee9a2cf9a97 100644
--- a/library/proc_macro/src/bridge/rpc.rs
+++ b/library/proc_macro/src/bridge/rpc.rs
@@ -114,7 +114,7 @@ impl<S> DecodeMut<'_, '_, S> for () {
 
 impl<S> Encode<S> for u8 {
     fn encode(self, w: &mut Writer, _: &mut S) {
-        w.write_all(&[self]).unwrap();
+        w.push(self);
     }
 }