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.
This commit is contained in:
Lena Hellström 2020-03-18 14:54:54 -07:00 committed by GitHub
parent 38322212e6
commit 15379ee5b2
1 changed files with 13 additions and 6 deletions

View File

@ -52,10 +52,9 @@ impl<'storage> SliceReader<'storage> {
if length > self.slice.len() { if length > self.slice.len() {
return Err(SliceReader::unexpected_eof()); return Err(SliceReader::unexpected_eof());
} }
let (read_slice, remaining) = self.slice.split_at(length);
let s = &self.slice[..length]; self.slice = remaining;
self.slice = &self.slice[length..]; Ok(read_slice)
Ok(s)
} }
} }
@ -72,11 +71,19 @@ impl<R> IoReader<R> {
impl<'storage> io::Read for SliceReader<'storage> { impl<'storage> io::Read for SliceReader<'storage> {
#[inline(always)] #[inline(always)]
fn read(&mut self, out: &mut [u8]) -> io::Result<usize> { fn read(&mut self, out: &mut [u8]) -> io::Result<usize> {
(&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)] #[inline(always)]
fn read_exact(&mut self, out: &mut [u8]) -> io::Result<()> { fn read_exact(&mut self, out: &mut [u8]) -> io::Result<()> {
(&mut self.slice).read_exact(out) self.read(out).map(|_|())
} }
} }