io: add #[inline] to IO trait impls for in-memory types (#8242)

Add #[inline] hints to poll_read, poll_write, start_seek, poll_complete, poll_fill_buf, and consume implementations for in-memory types (&[u8], Vec<u8>, Cursor<T>).

These are small, leaf implementations that benefit from cross-crate inlining, enabling LLVM to optimize call sites in downstream crates (including bounds-check elision and dead-code path elimination).

Benchmarks show ~16% improvement for slice reads and ~20% for cursor writes.
This commit is contained in:
ebubekir karaca
2026-07-01 18:28:37 +02:00
committed by GitHub
parent 98104c36f1
commit 448d1227a1
4 changed files with 33 additions and 0 deletions
+4
View File
@@ -97,20 +97,24 @@ where
}
impl AsyncBufRead for &[u8] {
#[inline]
fn poll_fill_buf(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
Poll::Ready(Ok(*self))
}
#[inline]
fn consume(mut self: Pin<&mut Self>, amt: usize) {
*self = &self[amt..];
}
}
impl<T: AsRef<[u8]> + Unpin> AsyncBufRead for io::Cursor<T> {
#[inline]
fn poll_fill_buf(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
Poll::Ready(io::BufRead::fill_buf(self.get_mut()))
}
#[inline]
fn consume(self: Pin<&mut Self>, amt: usize) {
io::BufRead::consume(self.get_mut(), amt);
}
+2
View File
@@ -94,6 +94,7 @@ where
}
impl AsyncRead for &[u8] {
#[inline]
fn poll_read(
mut self: Pin<&mut Self>,
_cx: &mut Context<'_>,
@@ -108,6 +109,7 @@ impl AsyncRead for &[u8] {
}
impl<T: AsRef<[u8]> + Unpin> AsyncRead for io::Cursor<T> {
#[inline]
fn poll_read(
mut self: Pin<&mut Self>,
_cx: &mut Context<'_>,
+2
View File
@@ -87,9 +87,11 @@ where
}
impl<T: AsRef<[u8]> + Unpin> AsyncSeek for io::Cursor<T> {
#[inline]
fn start_seek(mut self: Pin<&mut Self>, pos: SeekFrom) -> io::Result<()> {
io::Seek::seek(&mut *self, pos).map(drop)
}
#[inline]
fn poll_complete(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<u64>> {
Poll::Ready(Ok(self.get_mut().position()))
}
+25
View File
@@ -251,6 +251,7 @@ where
}
impl AsyncWrite for Vec<u8> {
#[inline]
fn poll_write(
self: Pin<&mut Self>,
_cx: &mut Context<'_>,
@@ -260,6 +261,7 @@ impl AsyncWrite for Vec<u8> {
Poll::Ready(Ok(buf.len()))
}
#[inline]
fn poll_write_vectored(
mut self: Pin<&mut Self>,
_: &mut Context<'_>,
@@ -268,20 +270,24 @@ impl AsyncWrite for Vec<u8> {
Poll::Ready(io::Write::write_vectored(&mut *self, bufs))
}
#[inline]
fn is_write_vectored(&self) -> bool {
true
}
#[inline]
fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
Poll::Ready(Ok(()))
}
#[inline]
fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
Poll::Ready(Ok(()))
}
}
impl AsyncWrite for io::Cursor<&mut [u8]> {
#[inline]
fn poll_write(
mut self: Pin<&mut Self>,
_: &mut Context<'_>,
@@ -290,6 +296,7 @@ impl AsyncWrite for io::Cursor<&mut [u8]> {
Poll::Ready(io::Write::write(&mut *self, buf))
}
#[inline]
fn poll_write_vectored(
mut self: Pin<&mut Self>,
_: &mut Context<'_>,
@@ -298,20 +305,24 @@ impl AsyncWrite for io::Cursor<&mut [u8]> {
Poll::Ready(io::Write::write_vectored(&mut *self, bufs))
}
#[inline]
fn is_write_vectored(&self) -> bool {
true
}
#[inline]
fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
Poll::Ready(io::Write::flush(&mut *self))
}
#[inline]
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.poll_flush(cx)
}
}
impl AsyncWrite for io::Cursor<&mut Vec<u8>> {
#[inline]
fn poll_write(
mut self: Pin<&mut Self>,
_: &mut Context<'_>,
@@ -320,6 +331,7 @@ impl AsyncWrite for io::Cursor<&mut Vec<u8>> {
Poll::Ready(io::Write::write(&mut *self, buf))
}
#[inline]
fn poll_write_vectored(
mut self: Pin<&mut Self>,
_: &mut Context<'_>,
@@ -328,20 +340,24 @@ impl AsyncWrite for io::Cursor<&mut Vec<u8>> {
Poll::Ready(io::Write::write_vectored(&mut *self, bufs))
}
#[inline]
fn is_write_vectored(&self) -> bool {
true
}
#[inline]
fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
Poll::Ready(io::Write::flush(&mut *self))
}
#[inline]
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.poll_flush(cx)
}
}
impl AsyncWrite for io::Cursor<Vec<u8>> {
#[inline]
fn poll_write(
mut self: Pin<&mut Self>,
_: &mut Context<'_>,
@@ -350,6 +366,7 @@ impl AsyncWrite for io::Cursor<Vec<u8>> {
Poll::Ready(io::Write::write(&mut *self, buf))
}
#[inline]
fn poll_write_vectored(
mut self: Pin<&mut Self>,
_: &mut Context<'_>,
@@ -358,20 +375,24 @@ impl AsyncWrite for io::Cursor<Vec<u8>> {
Poll::Ready(io::Write::write_vectored(&mut *self, bufs))
}
#[inline]
fn is_write_vectored(&self) -> bool {
true
}
#[inline]
fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
Poll::Ready(io::Write::flush(&mut *self))
}
#[inline]
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.poll_flush(cx)
}
}
impl AsyncWrite for io::Cursor<Box<[u8]>> {
#[inline]
fn poll_write(
mut self: Pin<&mut Self>,
_: &mut Context<'_>,
@@ -380,6 +401,7 @@ impl AsyncWrite for io::Cursor<Box<[u8]>> {
Poll::Ready(io::Write::write(&mut *self, buf))
}
#[inline]
fn poll_write_vectored(
mut self: Pin<&mut Self>,
_: &mut Context<'_>,
@@ -388,14 +410,17 @@ impl AsyncWrite for io::Cursor<Box<[u8]>> {
Poll::Ready(io::Write::write_vectored(&mut *self, bufs))
}
#[inline]
fn is_write_vectored(&self) -> bool {
true
}
#[inline]
fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
Poll::Ready(io::Write::flush(&mut *self))
}
#[inline]
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.poll_flush(cx)
}