diff --git a/benches/bytes.rs b/benches/bytes.rs index 4232ced..ff07395 100644 --- a/benches/bytes.rs +++ b/benches/bytes.rs @@ -4,7 +4,7 @@ extern crate bytes; extern crate test; use test::Bencher; -use bytes::{BytesMut, BufMut}; +use bytes::{Bytes, BytesMut, BufMut}; #[bench] fn alloc_small(b: &mut Bencher) { @@ -126,3 +126,23 @@ fn drain_write_drain(b: &mut Bencher) { test::black_box(parts); }) } + +#[bench] +fn slice_empty(b: &mut Bencher) { + b.iter(|| { + // Use empty vec to avoid measure of allocation/deallocation + let bytes = Bytes::from(Vec::new()); + (bytes.slice(0, 0), bytes) + }) +} + +#[bench] +fn slice_not_empty(b: &mut Bencher) { + b.iter(|| { + let b = Bytes::from(b"aabbccddeeffgghh".to_vec()); + for _ in 0..1024 { + test::black_box(b.slice(3, 5)); + test::black_box(&b); + } + }) +} diff --git a/src/bytes.rs b/src/bytes.rs index 6246509..4b0ef42 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -464,6 +464,11 @@ impl Bytes { /// Requires that `begin <= end` and `end <= self.len()`, otherwise slicing /// will panic. pub fn slice(&self, begin: usize, end: usize) -> Bytes { + if begin == end { + assert!(begin <= self.len()); + return Bytes::new(); + } + let mut ret = self.clone(); unsafe { diff --git a/tests/test_bytes.rs b/tests/test_bytes.rs index af481a2..c8d23d3 100644 --- a/tests/test_bytes.rs +++ b/tests/test_bytes.rs @@ -79,6 +79,15 @@ fn slice() { let b = a.slice(3, 5); assert_eq!(b, b"lo"[..]); + let b = a.slice(0, 0); + assert_eq!(b, b""[..]); + + let b = a.slice(3, 3); + assert_eq!(b, b""[..]); + + let b = a.slice(a.len(), a.len()); + assert_eq!(b, b""[..]); + let b = a.slice_to(5); assert_eq!(b, b"hello"[..]);