Faster From<[u8]> for BytesMut, remove panic in fmt::Write (#133)

* use slice.to_vec instead of buf.put in From<[u8]>

* don't panic in fmt::Write for BytesMut
This commit is contained in:
Sean McArthur
2017-06-15 10:55:02 -07:00
committed by Carl Lerche
parent 3240fb9cd9
commit 7e8373da8d
3 changed files with 55 additions and 6 deletions
+24
View File
@@ -127,6 +127,30 @@ fn drain_write_drain(b: &mut Bencher) {
}) })
} }
#[bench]
fn fmt_write(b: &mut Bencher) {
use std::fmt::Write;
let mut buf = BytesMut::with_capacity(128);
let s = "foo bar baz quux lorem ipsum dolor et";
b.bytes = s.len() as u64;
b.iter(|| {
let _ = write!(buf, "{}", s);
test::black_box(&buf);
unsafe { buf.set_len(0); }
})
}
#[bench]
fn from_long_slice(b: &mut Bencher) {
let data = [0u8; 128];
b.bytes = data.len() as u64;
b.iter(|| {
let buf = BytesMut::from(&data[..]);
test::black_box(buf);
})
}
#[bench] #[bench]
fn slice_empty(b: &mut Bencher) { fn slice_empty(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
+9 -6
View File
@@ -1418,10 +1418,7 @@ impl<'a> From<&'a [u8]> for BytesMut {
} }
} }
} else { } else {
let mut buf = BytesMut::with_capacity(src.len()); BytesMut::from(src.to_vec())
let src: &[u8] = src.as_ref();
buf.put(src);
buf
} }
} }
} }
@@ -1487,11 +1484,17 @@ impl Borrow<[u8]> for BytesMut {
} }
impl fmt::Write for BytesMut { impl fmt::Write for BytesMut {
#[inline]
fn write_str(&mut self, s: &str) -> fmt::Result { fn write_str(&mut self, s: &str) -> fmt::Result {
BufMut::put(self, s); if self.remaining_mut() >= s.len() {
Ok(()) self.put_slice(s.as_bytes());
Ok(())
} else {
Err(fmt::Error)
}
} }
#[inline]
fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result { fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result {
fmt::write(self, args) fmt::write(self, args)
} }
+22
View File
@@ -51,6 +51,28 @@ fn fmt() {
assert_eq!(a, b); assert_eq!(a, b);
} }
#[test]
fn fmt_write() {
use std::fmt::Write;
use std::iter::FromIterator;
let s = String::from_iter((0..10).map(|_| "abcdefg"));
let mut a = BytesMut::with_capacity(64);
write!(a, "{}", &s[..64]).unwrap();
assert_eq!(a, s[..64].as_bytes());
let mut b = BytesMut::with_capacity(64);
write!(b, "{}", &s[..32]).unwrap();
write!(b, "{}", &s[32..64]).unwrap();
assert_eq!(b, s[..64].as_bytes());
let mut c = BytesMut::with_capacity(64);
write!(c, "{}", s).unwrap_err();
assert!(c.is_empty());
}
#[test] #[test]
fn len() { fn len() {
let a = Bytes::from(&b"abcdefg"[..]); let a = Bytes::from(&b"abcdefg"[..]);