From 7e8373da8d7e4553bbf9793c664fc200f2f61046 Mon Sep 17 00:00:00 2001 From: Sean McArthur <sean.monstar@gmail.com> Date: Thu, 15 Jun 2017 10:55:02 -0700 Subject: [PATCH] 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 --- benches/bytes.rs | 24 ++++++++++++++++++++++++ src/bytes.rs | 15 +++++++++------ tests/test_bytes.rs | 22 ++++++++++++++++++++++ 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/benches/bytes.rs b/benches/bytes.rs index ff07395..86eb9c4 100644 --- a/benches/bytes.rs +++ b/benches/bytes.rs @@ -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] fn slice_empty(b: &mut Bencher) { b.iter(|| { diff --git a/src/bytes.rs b/src/bytes.rs index fd0317d..5945f3d 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -1418,10 +1418,7 @@ impl<'a> From<&'a [u8]> for BytesMut { } } } else { - let mut buf = BytesMut::with_capacity(src.len()); - let src: &[u8] = src.as_ref(); - buf.put(src); - buf + BytesMut::from(src.to_vec()) } } } @@ -1487,11 +1484,17 @@ impl Borrow<[u8]> for BytesMut { } impl fmt::Write for BytesMut { + #[inline] fn write_str(&mut self, s: &str) -> fmt::Result { - BufMut::put(self, s); - Ok(()) + if self.remaining_mut() >= s.len() { + self.put_slice(s.as_bytes()); + Ok(()) + } else { + Err(fmt::Error) + } } + #[inline] fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result { fmt::write(self, args) } diff --git a/tests/test_bytes.rs b/tests/test_bytes.rs index c8d23d3..b966fe0 100644 --- a/tests/test_bytes.rs +++ b/tests/test_bytes.rs @@ -51,6 +51,28 @@ fn fmt() { 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] fn len() { let a = Bytes::from(&b"abcdefg"[..]); -- GitLab