aboutsummaryrefslogtreecommitdiff
path: root/benches
diff options
context:
space:
mode:
authorChih-Hung Hsieh <chh@google.com>2020-06-10 20:15:59 -0700
committerChih-Hung Hsieh <chh@google.com>2020-06-10 20:15:59 -0700
commit01ae379526218e7f6ca28510b6c06098419b7380 (patch)
treeded7cfd36c57807924e0b2e62439a8df9f6d32c1 /benches
parent7457df12a2eb70afcfa283968f7d1fadf123b0a1 (diff)
downloadbytes-01ae379526218e7f6ca28510b6c06098419b7380.tar.gz
Import bytes-0.5.4
* Add OWNERS and Android.bp Bug: 143953733 Test: make Change-Id: Ica69d7252abb1c2967f2c0e11a62d0bd83192fb3
Diffstat (limited to 'benches')
-rw-r--r--benches/buf.rs187
-rw-r--r--benches/bytes.rs118
-rw-r--r--benches/bytes_mut.rs249
3 files changed, 554 insertions, 0 deletions
diff --git a/benches/buf.rs b/benches/buf.rs
new file mode 100644
index 0000000..0c9a1d9
--- /dev/null
+++ b/benches/buf.rs
@@ -0,0 +1,187 @@
+#![feature(test)]
+#![deny(warnings, rust_2018_idioms)]
+
+extern crate test;
+
+use test::Bencher;
+use bytes::Buf;
+
+/// Dummy Buf implementation
+struct TestBuf {
+ buf: &'static [u8],
+ readlens: &'static [usize],
+ init_pos: usize,
+ pos: usize,
+ readlen_pos: usize,
+ readlen: usize,
+}
+impl TestBuf {
+ fn new(buf: &'static [u8], readlens: &'static [usize], init_pos: usize) -> TestBuf {
+ let mut buf = TestBuf {
+ buf,
+ readlens,
+ init_pos,
+ pos: 0,
+ readlen_pos: 0,
+ readlen: 0,
+ };
+ buf.reset();
+ buf
+ }
+ fn reset(&mut self) {
+ self.pos = self.init_pos;
+ self.readlen_pos = 0;
+ self.next_readlen();
+ }
+ /// Compute the length of the next read :
+ /// - use the next value specified in readlens (capped by remaining) if any
+ /// - else the remaining
+ fn next_readlen(&mut self) {
+ self.readlen = self.buf.len() - self.pos;
+ if let Some(readlen) = self.readlens.get(self.readlen_pos) {
+ self.readlen = std::cmp::min(self.readlen, *readlen);
+ self.readlen_pos += 1;
+ }
+ }
+}
+impl Buf for TestBuf {
+ fn remaining(&self) -> usize {
+ return self.buf.len() - self.pos;
+ }
+ fn advance(&mut self, cnt: usize) {
+ self.pos += cnt;
+ assert!(self.pos <= self.buf.len());
+ self.next_readlen();
+ }
+ fn bytes(&self) -> &[u8] {
+ if self.readlen == 0 {
+ Default::default()
+ } else {
+ &self.buf[self.pos..self.pos + self.readlen]
+ }
+ }
+}
+
+/// Dummy Buf implementation
+/// version with methods forced to not be inlined (to simulate costly calls)
+struct TestBufC {
+ inner: TestBuf,
+}
+impl TestBufC {
+ fn new(buf: &'static [u8], readlens: &'static [usize], init_pos: usize) -> TestBufC {
+ TestBufC {
+ inner: TestBuf::new(buf, readlens, init_pos),
+ }
+ }
+ fn reset(&mut self) {
+ self.inner.reset()
+ }
+}
+impl Buf for TestBufC {
+ #[inline(never)]
+ fn remaining(&self) -> usize {
+ self.inner.remaining()
+ }
+ #[inline(never)]
+ fn advance(&mut self, cnt: usize) {
+ self.inner.advance(cnt)
+ }
+ #[inline(never)]
+ fn bytes(&self) -> &[u8] {
+ self.inner.bytes()
+ }
+}
+
+macro_rules! bench {
+ ($fname:ident, testbuf $testbuf:ident $readlens:expr, $method:ident $(,$arg:expr)*) => (
+ #[bench]
+ fn $fname(b: &mut Bencher) {
+ let mut bufs = [
+ $testbuf::new(&[1u8; 8+0], $readlens, 0),
+ $testbuf::new(&[1u8; 8+1], $readlens, 1),
+ $testbuf::new(&[1u8; 8+2], $readlens, 2),
+ $testbuf::new(&[1u8; 8+3], $readlens, 3),
+ $testbuf::new(&[1u8; 8+4], $readlens, 4),
+ $testbuf::new(&[1u8; 8+5], $readlens, 5),
+ $testbuf::new(&[1u8; 8+6], $readlens, 6),
+ $testbuf::new(&[1u8; 8+7], $readlens, 7),
+ ];
+ b.iter(|| {
+ for i in 0..8 {
+ bufs[i].reset();
+ let buf: &mut dyn Buf = &mut bufs[i]; // type erasure
+ test::black_box(buf.$method($($arg,)*));
+ }
+ })
+ }
+ );
+ ($fname:ident, slice, $method:ident $(,$arg:expr)*) => (
+ #[bench]
+ fn $fname(b: &mut Bencher) {
+ // buf must be long enough for one read of 8 bytes starting at pos 7
+ let arr = [1u8; 8+7];
+ b.iter(|| {
+ for i in 0..8 {
+ let mut buf = &arr[i..];
+ let buf = &mut buf as &mut dyn Buf; // type erasure
+ test::black_box(buf.$method($($arg,)*));
+ }
+ })
+ }
+ );
+ ($fname:ident, option) => (
+ #[bench]
+ fn $fname(b: &mut Bencher) {
+ let data = [1u8; 1];
+ b.iter(|| {
+ for _ in 0..8 {
+ let mut buf = Some(data);
+ let buf = &mut buf as &mut dyn Buf; // type erasure
+ test::black_box(buf.get_u8());
+ }
+ })
+ }
+ );
+}
+
+macro_rules! bench_group {
+ ($method:ident $(,$arg:expr)*) => (
+ bench!(slice, slice, $method $(,$arg)*);
+ bench!(tbuf_1, testbuf TestBuf &[], $method $(,$arg)*);
+ bench!(tbuf_1_costly, testbuf TestBufC &[], $method $(,$arg)*);
+ bench!(tbuf_2, testbuf TestBuf &[1], $method $(,$arg)*);
+ bench!(tbuf_2_costly, testbuf TestBufC &[1], $method $(,$arg)*);
+ // bench!(tbuf_onebyone, testbuf TestBuf &[1,1,1,1,1,1,1,1], $method $(,$arg)*);
+ // bench!(tbuf_onebyone_costly, testbuf TestBufC &[1,1,1,1,1,1,1,1], $method $(,$arg)*);
+ );
+}
+
+mod get_u8 {
+ use super::*;
+ bench_group!(get_u8);
+ bench!(option, option);
+}
+mod get_u16 {
+ use super::*;
+ bench_group!(get_u16);
+}
+mod get_u32 {
+ use super::*;
+ bench_group!(get_u32);
+}
+mod get_u64 {
+ use super::*;
+ bench_group!(get_u64);
+}
+mod get_f32 {
+ use super::*;
+ bench_group!(get_f32);
+}
+mod get_f64 {
+ use super::*;
+ bench_group!(get_f64);
+}
+mod get_uint24 {
+ use super::*;
+ bench_group!(get_uint, 3);
+}
diff --git a/benches/bytes.rs b/benches/bytes.rs
new file mode 100644
index 0000000..9c36e60
--- /dev/null
+++ b/benches/bytes.rs
@@ -0,0 +1,118 @@
+#![feature(test)]
+#![deny(warnings, rust_2018_idioms)]
+
+extern crate test;
+
+use test::Bencher;
+use bytes::Bytes;
+
+#[bench]
+fn deref_unique(b: &mut Bencher) {
+ let buf = Bytes::from(vec![0; 1024]);
+
+ b.iter(|| {
+ for _ in 0..1024 {
+ test::black_box(&buf[..]);
+ }
+ })
+}
+
+#[bench]
+fn deref_shared(b: &mut Bencher) {
+ let buf = Bytes::from(vec![0; 1024]);
+ let _b2 = buf.clone();
+
+ b.iter(|| {
+ for _ in 0..1024 {
+ test::black_box(&buf[..]);
+ }
+ })
+}
+
+#[bench]
+fn deref_static(b: &mut Bencher) {
+ let buf = Bytes::from_static(b"hello world");
+
+ b.iter(|| {
+ for _ in 0..1024 {
+ test::black_box(&buf[..]);
+ }
+ })
+}
+
+#[bench]
+fn clone_static(b: &mut Bencher) {
+ let bytes = Bytes::from_static("hello world 1234567890 and have a good byte 0987654321".as_bytes());
+
+ b.iter(|| {
+ for _ in 0..1024 {
+ test::black_box(&bytes.clone());
+ }
+ })
+}
+
+#[bench]
+fn clone_shared(b: &mut Bencher) {
+ let bytes = Bytes::from(b"hello world 1234567890 and have a good byte 0987654321".to_vec());
+
+ b.iter(|| {
+ for _ in 0..1024 {
+ test::black_box(&bytes.clone());
+ }
+ })
+}
+
+#[bench]
+fn clone_arc_vec(b: &mut Bencher) {
+ use std::sync::Arc;
+ let bytes = Arc::new(b"hello world 1234567890 and have a good byte 0987654321".to_vec());
+
+ b.iter(|| {
+ for _ in 0..1024 {
+ test::black_box(&bytes.clone());
+ }
+ })
+}
+
+#[bench]
+fn from_long_slice(b: &mut Bencher) {
+ let data = [0u8; 128];
+ b.bytes = data.len() as u64;
+ b.iter(|| {
+ let buf = Bytes::copy_from_slice(&data[..]);
+ test::black_box(buf);
+ })
+}
+
+#[bench]
+fn slice_empty(b: &mut Bencher) {
+ b.iter(|| {
+ let b = Bytes::from(vec![17; 1024]).clone();
+ for i in 0..1000 {
+ test::black_box(b.slice(i % 100..i % 100));
+ }
+ })
+}
+
+#[bench]
+fn slice_short_from_arc(b: &mut Bencher) {
+ b.iter(|| {
+ // `clone` is to convert to ARC
+ let b = Bytes::from(vec![17; 1024]).clone();
+ for i in 0..1000 {
+ test::black_box(b.slice(1..2 + i % 10));
+ }
+ })
+}
+
+#[bench]
+fn split_off_and_drop(b: &mut Bencher) {
+ b.iter(|| {
+ for _ in 0..1024 {
+ let v = vec![10; 200];
+ let mut b = Bytes::from(v);
+ test::black_box(b.split_off(100));
+ test::black_box(b);
+ }
+ })
+}
diff --git a/benches/bytes_mut.rs b/benches/bytes_mut.rs
new file mode 100644
index 0000000..ded1d14
--- /dev/null
+++ b/benches/bytes_mut.rs
@@ -0,0 +1,249 @@
+#![feature(test)]
+#![deny(warnings, rust_2018_idioms)]
+
+extern crate test;
+
+use test::Bencher;
+use bytes::{BufMut, BytesMut};
+
+#[bench]
+fn alloc_small(b: &mut Bencher) {
+ b.iter(|| {
+ for _ in 0..1024 {
+ test::black_box(BytesMut::with_capacity(12));
+ }
+ })
+}
+
+#[bench]
+fn alloc_mid(b: &mut Bencher) {
+ b.iter(|| {
+ test::black_box(BytesMut::with_capacity(128));
+ })
+}
+
+#[bench]
+fn alloc_big(b: &mut Bencher) {
+ b.iter(|| {
+ test::black_box(BytesMut::with_capacity(4096));
+ })
+}
+
+
+#[bench]
+fn deref_unique(b: &mut Bencher) {
+ let mut buf = BytesMut::with_capacity(4096);
+ buf.put(&[0u8; 1024][..]);
+
+ b.iter(|| {
+ for _ in 0..1024 {
+ test::black_box(&buf[..]);
+ }
+ })
+}
+
+#[bench]
+fn deref_unique_unroll(b: &mut Bencher) {
+ let mut buf = BytesMut::with_capacity(4096);
+ buf.put(&[0u8; 1024][..]);
+
+ b.iter(|| {
+ for _ in 0..128 {
+ test::black_box(&buf[..]);
+ test::black_box(&buf[..]);
+ test::black_box(&buf[..]);
+ test::black_box(&buf[..]);
+ test::black_box(&buf[..]);
+ test::black_box(&buf[..]);
+ test::black_box(&buf[..]);
+ test::black_box(&buf[..]);
+ }
+ })
+}
+
+#[bench]
+fn deref_shared(b: &mut Bencher) {
+ let mut buf = BytesMut::with_capacity(4096);
+ buf.put(&[0u8; 1024][..]);
+ let _b2 = buf.split_off(1024);
+
+ b.iter(|| {
+ for _ in 0..1024 {
+ test::black_box(&buf[..]);
+ }
+ })
+}
+
+#[bench]
+fn deref_two(b: &mut Bencher) {
+ let mut buf1 = BytesMut::with_capacity(8);
+ buf1.put(&[0u8; 8][..]);
+
+ let mut buf2 = BytesMut::with_capacity(4096);
+ buf2.put(&[0u8; 1024][..]);
+
+ b.iter(|| {
+ for _ in 0..512 {
+ test::black_box(&buf1[..]);
+ test::black_box(&buf2[..]);
+ }
+ })
+}
+
+#[bench]
+fn clone_frozen(b: &mut Bencher) {
+ let bytes = BytesMut::from(&b"hello world 1234567890 and have a good byte 0987654321"[..]).split().freeze();
+
+ b.iter(|| {
+ for _ in 0..1024 {
+ test::black_box(&bytes.clone());
+ }
+ })
+}
+
+#[bench]
+fn alloc_write_split_to_mid(b: &mut Bencher) {
+ b.iter(|| {
+ let mut buf = BytesMut::with_capacity(128);
+ buf.put_slice(&[0u8; 64]);
+ test::black_box(buf.split_to(64));
+ })
+}
+
+#[bench]
+fn drain_write_drain(b: &mut Bencher) {
+ let data = [0u8; 128];
+
+ b.iter(|| {
+ let mut buf = BytesMut::with_capacity(1024);
+ let mut parts = Vec::with_capacity(8);
+
+ for _ in 0..8 {
+ buf.put(&data[..]);
+ parts.push(buf.split_to(128));
+ }
+
+ test::black_box(parts);
+ })
+}
+
+#[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 bytes_mut_extend(b: &mut Bencher) {
+ let mut buf = BytesMut::with_capacity(256);
+ let data = [33u8; 32];
+
+ b.bytes = data.len() as u64 * 4;
+ b.iter(|| {
+ for _ in 0..4 {
+ buf.extend(&data);
+ }
+ test::black_box(&buf);
+ unsafe { buf.set_len(0); }
+ });
+}
+
+// BufMut for BytesMut vs Vec<u8>
+
+#[bench]
+fn put_slice_bytes_mut(b: &mut Bencher) {
+ let mut buf = BytesMut::with_capacity(256);
+ let data = [33u8; 32];
+
+ b.bytes = data.len() as u64 * 4;
+ b.iter(|| {
+ for _ in 0..4 {
+ buf.put_slice(&data);
+ }
+ test::black_box(&buf);
+ unsafe { buf.set_len(0); }
+ });
+}
+
+#[bench]
+fn put_u8_bytes_mut(b: &mut Bencher) {
+ let mut buf = BytesMut::with_capacity(256);
+ let cnt = 128;
+
+ b.bytes = cnt as u64;
+ b.iter(|| {
+ for _ in 0..cnt {
+ buf.put_u8(b'x');
+ }
+ test::black_box(&buf);
+ unsafe { buf.set_len(0); }
+ });
+}
+
+#[bench]
+fn put_slice_vec(b: &mut Bencher) {
+ let mut buf = Vec::<u8>::with_capacity(256);
+ let data = [33u8; 32];
+
+ b.bytes = data.len() as u64 * 4;
+ b.iter(|| {
+ for _ in 0..4 {
+ buf.put_slice(&data);
+ }
+ test::black_box(&buf);
+ unsafe { buf.set_len(0); }
+ });
+}
+
+#[bench]
+fn put_u8_vec(b: &mut Bencher) {
+ let mut buf = Vec::<u8>::with_capacity(256);
+ let cnt = 128;
+
+ b.bytes = cnt as u64;
+ b.iter(|| {
+ for _ in 0..cnt {
+ buf.put_u8(b'x');
+ }
+ test::black_box(&buf);
+ unsafe { buf.set_len(0); }
+ });
+}
+
+#[bench]
+fn put_slice_vec_extend(b: &mut Bencher) {
+ let mut buf = Vec::<u8>::with_capacity(256);
+ let data = [33u8; 32];
+
+ b.bytes = data.len() as u64 * 4;
+ b.iter(|| {
+ for _ in 0..4 {
+ buf.extend_from_slice(&data);
+ }
+ test::black_box(&buf);
+ unsafe { buf.set_len(0); }
+ });
+}
+
+#[bench]
+fn put_u8_vec_push(b: &mut Bencher) {
+ let mut buf = Vec::<u8>::with_capacity(256);
+ let cnt = 128;
+
+ b.bytes = cnt as u64;
+ b.iter(|| {
+ for _ in 0..cnt {
+ buf.push(b'x');
+ }
+ test::black_box(&buf);
+ unsafe { buf.set_len(0); }
+ });
+}