From 15379ee5b2d19bb93d304f74b8fe3ae41124dc4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lena=20Hellstr=C3=B6m?= Date: Wed, 18 Mar 2020 14:54:54 -0700 Subject: [PATCH] Overoptimize slice reader (#308) The default read implementation on slices was not generating efficient code. This custom implementation generates much smaller assembly with fewer function calls. --- src/de/read.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/de/read.rs b/src/de/read.rs index 82314fe..9a0489a 100644 --- a/src/de/read.rs +++ b/src/de/read.rs @@ -52,10 +52,9 @@ impl<'storage> SliceReader<'storage> { if length > self.slice.len() { return Err(SliceReader::unexpected_eof()); } - - let s = &self.slice[..length]; - self.slice = &self.slice[length..]; - Ok(s) + let (read_slice, remaining) = self.slice.split_at(length); + self.slice = remaining; + Ok(read_slice) } } @@ -72,11 +71,19 @@ impl IoReader { impl<'storage> io::Read for SliceReader<'storage> { #[inline(always)] fn read(&mut self, out: &mut [u8]) -> io::Result { - (&mut self.slice).read(out) + if out.len() > self.slice.len() { + return Err(io::ErrorKind::UnexpectedEof.into()); + } + let (read_slice, remaining) = self.slice.split_at(out.len()); + out.copy_from_slice(read_slice); + self.slice = remaining; + + Ok(out.len()) } + #[inline(always)] fn read_exact(&mut self, out: &mut [u8]) -> io::Result<()> { - (&mut self.slice).read_exact(out) + self.read(out).map(|_|()) } }