fn copy_from_slice(&mut self, src: &[T]) where T: Copy {
assert!(self.len() == src.len(),
"destination and source slices have different lengths");
- // First check if the amount of elements we want to copy is small:
- // `copy_nonoverlapping` will do a memcopy, which involves an indirect
- // function call when `memcpy` is in the dynamically-linked libc. For
- // small elements (such as a single byte or pointer), the overhead is
- // significant. If the element is big then the assignment is a memcopy
- // anyway.
- if self.len() == 1 {
- self[0] = src[0];
- } else {
- unsafe {
- ptr::copy_nonoverlapping(
- src.as_ptr(), self.as_mut_ptr(), self.len());
- }
+ unsafe {
+ ptr::copy_nonoverlapping(
+ src.as_ptr(), self.as_mut_ptr(), self.len());
}
}
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let amt = cmp::min(buf.len(), self.len());
let (a, b) = self.split_at(amt);
- buf[..amt].copy_from_slice(a);
+
+ // First check if the amount of bytes we want to read is small:
+ // `copy_from_slice` will generally expand to a call to `memcpy`, and
+ // for a single byte the overhead is significant.
+ if amt == 1 {
+ buf[0] = a[0];
+ } else {
+ buf[..amt].copy_from_slice(a);
+ }
+
*self = b;
Ok(amt)
}
"failed to fill whole buffer"));
}
let (a, b) = self.split_at(buf.len());
- buf.copy_from_slice(a);
+
+ // First check if the amount of bytes we want to read is small:
+ // `copy_from_slice` will generally expand to a call to `memcpy`, and
+ // for a single byte the overhead is significant.
+ if buf.len() == 1 {
+ buf[0] = a[0];
+ } else {
+ buf.copy_from_slice(a);
+ }
+
*self = b;
Ok(())
}