From 448d1227a1e07fb3649f0f0663f27d6137073db7 Mon Sep 17 00:00:00 2001 From: ebubekir karaca <31825198+YatogamiRaito@users.noreply.github.com> Date: Wed, 1 Jul 2026 19:28:37 +0300 Subject: [PATCH] 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, Cursor). 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. --- tokio/src/io/async_buf_read.rs | 4 ++++ tokio/src/io/async_read.rs | 2 ++ tokio/src/io/async_seek.rs | 2 ++ tokio/src/io/async_write.rs | 25 +++++++++++++++++++++++++ 4 files changed, 33 insertions(+) diff --git a/tokio/src/io/async_buf_read.rs b/tokio/src/io/async_buf_read.rs index f5ff88248..0336c383a 100644 --- a/tokio/src/io/async_buf_read.rs +++ b/tokio/src/io/async_buf_read.rs @@ -97,20 +97,24 @@ where } impl AsyncBufRead for &[u8] { + #[inline] fn poll_fill_buf(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(*self)) } + #[inline] fn consume(mut self: Pin<&mut Self>, amt: usize) { *self = &self[amt..]; } } impl + Unpin> AsyncBufRead for io::Cursor { + #[inline] fn poll_fill_buf(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { 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); } diff --git a/tokio/src/io/async_read.rs b/tokio/src/io/async_read.rs index 2efd9d11f..613f37249 100644 --- a/tokio/src/io/async_read.rs +++ b/tokio/src/io/async_read.rs @@ -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 + Unpin> AsyncRead for io::Cursor { + #[inline] fn poll_read( mut self: Pin<&mut Self>, _cx: &mut Context<'_>, diff --git a/tokio/src/io/async_seek.rs b/tokio/src/io/async_seek.rs index fbd1eafa0..9045995f7 100644 --- a/tokio/src/io/async_seek.rs +++ b/tokio/src/io/async_seek.rs @@ -87,9 +87,11 @@ where } impl + Unpin> AsyncSeek for io::Cursor { + #[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> { Poll::Ready(Ok(self.get_mut().position())) } diff --git a/tokio/src/io/async_write.rs b/tokio/src/io/async_write.rs index 68cee03c4..4906943c5 100644 --- a/tokio/src/io/async_write.rs +++ b/tokio/src/io/async_write.rs @@ -251,6 +251,7 @@ where } impl AsyncWrite for Vec { + #[inline] fn poll_write( self: Pin<&mut Self>, _cx: &mut Context<'_>, @@ -260,6 +261,7 @@ impl AsyncWrite for Vec { 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 { 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> { Poll::Ready(Ok(())) } + #[inline] fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { 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> { Poll::Ready(io::Write::flush(&mut *self)) } + #[inline] fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.poll_flush(cx) } } impl AsyncWrite for io::Cursor<&mut Vec> { + #[inline] fn poll_write( mut self: Pin<&mut Self>, _: &mut Context<'_>, @@ -320,6 +331,7 @@ impl AsyncWrite for io::Cursor<&mut Vec> { 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> { 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> { Poll::Ready(io::Write::flush(&mut *self)) } + #[inline] fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.poll_flush(cx) } } impl AsyncWrite for io::Cursor> { + #[inline] fn poll_write( mut self: Pin<&mut Self>, _: &mut Context<'_>, @@ -350,6 +366,7 @@ impl AsyncWrite for io::Cursor> { 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> { 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> { Poll::Ready(io::Write::flush(&mut *self)) } + #[inline] fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.poll_flush(cx) } } impl AsyncWrite for io::Cursor> { + #[inline] fn poll_write( mut self: Pin<&mut Self>, _: &mut Context<'_>, @@ -380,6 +401,7 @@ impl AsyncWrite for io::Cursor> { 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> { 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> { Poll::Ready(io::Write::flush(&mut *self)) } + #[inline] fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.poll_flush(cx) }