From 299ac7589410a4e9541d0483161abb9e455e0ec1 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 15 May 2021 18:54:57 -0400 Subject: [PATCH] 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. --- library/proc_macro/src/bridge/buffer.rs | 15 +++++++++++++++ library/proc_macro/src/bridge/rpc.rs | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) 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 @@ pub(super) fn extend_from_slice(&mut self, xs: &[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 { 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 @@ fn decode(_: &mut Reader<'_>, _: &mut S) -> Self {} impl Encode for u8 { fn encode(self, w: &mut Writer, _: &mut S) { - w.write_all(&[self]).unwrap(); + w.push(self); } }