diff options
| author | Mark Rousskov <mark.simulacrum@gmail.com> | 2021-05-15 18:54:57 -0400 |
|---|---|---|
| committer | Mark Rousskov <mark.simulacrum@gmail.com> | 2021-05-29 12:45:07 -0400 |
| commit | 299ac7589410a4e9541d0483161abb9e455e0ec1 (patch) | |
| tree | 5725b24abd6a332ea3f575fd861c12b023b1f4c0 | |
| parent | 9f75dbfa69ba8508fa7765305f75cd96dff06078 (diff) | |
| download | rust-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.rs | 15 | ||||
| -rw-r--r-- | library/proc_macro/src/bridge/rpc.rs | 2 |
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); } } |
