Skip to content

Commit 299ac75

Browse files
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.
1 parent 9f75dbf commit 299ac75

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

library/proc_macro/src/bridge/buffer.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,21 @@ impl<T: Copy> Buffer<T> {
9191
let b = self.take();
9292
*self = (b.extend_from_slice)(b, Slice::from(xs));
9393
}
94+
95+
pub(super) fn push(&mut self, v: T) {
96+
// Fast path to avoid going through an FFI call.
97+
if let Some(final_len) = self.len.checked_add(1) {
98+
if final_len <= self.capacity {
99+
unsafe {
100+
*self.data.add(self.len) = v;
101+
}
102+
self.len = final_len;
103+
return;
104+
}
105+
}
106+
let b = self.take();
107+
*self = (b.extend_from_slice)(b, Slice::from(std::slice::from_ref(&v)));
108+
}
94109
}
95110

96111
impl Write for Buffer<u8> {

library/proc_macro/src/bridge/rpc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ impl<S> DecodeMut<'_, '_, S> for () {
114114

115115
impl<S> Encode<S> for u8 {
116116
fn encode(self, w: &mut Writer, _: &mut S) {
117-
w.write_all(&[self]).unwrap();
117+
w.push(self);
118118
}
119119
}
120120

0 commit comments

Comments
 (0)