mirror of
https://github.com/tokio-rs/bytes.git
synced 2026-08-26 00:00:20 +02:00
Add a quick benchmark
This commit is contained in:
+1
-1
@@ -9,7 +9,7 @@ license = "MIT"
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
||||||
rand = "0.1.2"
|
rand = "0.1.2"
|
||||||
# iobuf = "*"
|
iobuf = "*"
|
||||||
|
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#![feature(test, core)]
|
||||||
|
|
||||||
|
use bytes::ByteBuf;
|
||||||
|
use bytes::traits::*;
|
||||||
|
use iobuf::{RWIobuf};
|
||||||
|
use test::Bencher;
|
||||||
|
|
||||||
|
extern crate bytes;
|
||||||
|
extern crate iobuf;
|
||||||
|
extern crate test;
|
||||||
|
|
||||||
|
const SIZE:usize = 4_096;
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
pub fn bench_byte_buf_fill_4kb(b: &mut Bencher) {
|
||||||
|
b.iter(|| {
|
||||||
|
let mut buf = ByteBuf::mut_with_capacity(SIZE);
|
||||||
|
|
||||||
|
for _ in 0..SIZE {
|
||||||
|
buf.write_slice(&[0]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
pub fn bench_rw_iobuf_fill_4kb(b: &mut Bencher) {
|
||||||
|
b.iter(|| {
|
||||||
|
let mut buf = RWIobuf::new(SIZE);
|
||||||
|
|
||||||
|
for _ in 0..SIZE {
|
||||||
|
let _ = buf.fill(&[0]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
+29
-16
@@ -1,5 +1,5 @@
|
|||||||
use {alloc, Bytes, SeqByteStr, BufResult, BufError, MAX_CAPACITY};
|
use {alloc, Bytes, SeqByteStr, MAX_CAPACITY};
|
||||||
use traits::{Buf, MutBuf, ByteStr};
|
use traits::{Buf, MutBuf, MutBufExt, ByteStr};
|
||||||
use std::{cmp, ptr};
|
use std::{cmp, ptr};
|
||||||
use std::num::UnsignedInt;
|
use std::num::UnsignedInt;
|
||||||
|
|
||||||
@@ -9,6 +9,7 @@ use std::num::UnsignedInt;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/// A `Buf` backed by a contiguous region of memory.
|
||||||
pub struct ByteBuf {
|
pub struct ByteBuf {
|
||||||
mem: alloc::MemRef,
|
mem: alloc::MemRef,
|
||||||
cap: u32,
|
cap: u32,
|
||||||
@@ -17,6 +18,7 @@ pub struct ByteBuf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ByteBuf {
|
impl ByteBuf {
|
||||||
|
/// Create a new `ByteBuf` by copying the contents of the given slice.
|
||||||
pub fn from_slice(bytes: &[u8]) -> ByteBuf {
|
pub fn from_slice(bytes: &[u8]) -> ByteBuf {
|
||||||
let mut buf = ByteBuf::mut_with_capacity(bytes.len());
|
let mut buf = ByteBuf::mut_with_capacity(bytes.len());
|
||||||
buf.write(bytes).ok().expect("unexpected failure");
|
buf.write(bytes).ok().expect("unexpected failure");
|
||||||
@@ -105,45 +107,46 @@ impl ByteBuf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn to_bytes(self) -> Bytes {
|
pub fn to_bytes(self) -> Bytes {
|
||||||
Bytes::of(self.to_seq_byte_str())
|
Bytes::of(self.to_seq_byte_str())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn pos(&self) -> usize {
|
fn pos(&self) -> usize {
|
||||||
self.pos as usize
|
self.pos as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn lim(&self) -> usize {
|
fn lim(&self) -> usize {
|
||||||
self.lim as usize
|
self.lim as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn remaining_u32(&self) -> u32 {
|
fn remaining_u32(&self) -> u32 {
|
||||||
self.lim - self.pos
|
self.lim - self.pos
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ensure_remaining(&self, cnt: usize) -> BufResult<()> {
|
|
||||||
if cnt > self.remaining() {
|
|
||||||
return Err(BufError::Overflow);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Buf for ByteBuf {
|
impl Buf for ByteBuf {
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn remaining(&self) -> usize {
|
fn remaining(&self) -> usize {
|
||||||
self.remaining_u32() as usize
|
self.remaining_u32() as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn bytes<'a>(&'a self) -> &'a [u8] {
|
fn bytes<'a>(&'a self) -> &'a [u8] {
|
||||||
&self.mem.bytes()[self.pos()..self.lim()]
|
&self.mem.bytes()[self.pos()..self.lim()]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn advance(&mut self, mut cnt: usize) {
|
fn advance(&mut self, mut cnt: usize) {
|
||||||
cnt = cmp::min(cnt, self.remaining());
|
cnt = cmp::min(cnt, self.remaining());
|
||||||
self.pos += cnt as u32;
|
self.pos += cnt as u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn read_slice(&mut self, dst: &mut [u8]) -> usize {
|
fn read_slice(&mut self, dst: &mut [u8]) -> usize {
|
||||||
ByteBuf::read_slice(self, dst)
|
ByteBuf::read_slice(self, dst)
|
||||||
}
|
}
|
||||||
@@ -225,18 +228,28 @@ impl MutByteBuf {
|
|||||||
self.buf.lim = self.buf.cap;
|
self.buf.lim = self.buf.cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_slice(&mut self, src: &[u8]) -> BufResult<()> {
|
#[inline]
|
||||||
try!(self.buf.ensure_remaining(src.len()));
|
pub fn write_slice(&mut self, src: &[u8]) -> usize {
|
||||||
let cnt = src.len() as u32;
|
let cnt = src.len() as u32;
|
||||||
|
let rem = self.buf.remaining_u32();
|
||||||
|
|
||||||
|
if rem < cnt {
|
||||||
|
self.write_ptr(src.as_ptr(), rem)
|
||||||
|
} else {
|
||||||
|
self.write_ptr(src.as_ptr(), cnt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn write_ptr(&mut self, src: *const u8, len: u32) -> usize {
|
||||||
unsafe {
|
unsafe {
|
||||||
ptr::copy_nonoverlapping_memory(
|
ptr::copy_nonoverlapping_memory(
|
||||||
self.buf.mem.ptr().offset(self.buf.pos as isize),
|
self.buf.mem.ptr().offset(self.buf.pos as isize),
|
||||||
src.as_ptr(), src.len());
|
src, len as usize);
|
||||||
}
|
|
||||||
|
|
||||||
self.buf.pos += cnt;
|
self.buf.pos += len;
|
||||||
return Ok(());
|
len as usize
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
use {alloc, Bytes, ByteBuf, ROByteBuf};
|
use {alloc, Bytes, ByteBuf, ROByteBuf};
|
||||||
use traits::{Buf, MutBuf, ByteStr};
|
use traits::{Buf, MutBuf, MutBufExt, ByteStr};
|
||||||
use std::{cmp, ops};
|
use std::{cmp, ops};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+16
-9
@@ -24,12 +24,12 @@ mod rope;
|
|||||||
mod slice;
|
mod slice;
|
||||||
|
|
||||||
pub mod traits {
|
pub mod traits {
|
||||||
pub use {Buf, BufExt, MutBuf, ByteStr};
|
pub use {Buf, BufExt, MutBuf, MutBufExt, ByteStr};
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_CAPACITY: usize = u32::MAX as usize;
|
const MAX_CAPACITY: usize = u32::MAX as usize;
|
||||||
|
|
||||||
/// A trait for objects that provide random and sequential access to bytes.
|
/// A trait for values that provide random and sequential access to bytes.
|
||||||
pub trait Buf {
|
pub trait Buf {
|
||||||
|
|
||||||
/// Returns the number of bytes that can be accessed from the Buf
|
/// Returns the number of bytes that can be accessed from the Buf
|
||||||
@@ -113,12 +113,6 @@ pub trait MutBuf : Sized {
|
|||||||
/// length between 0 and `Buf::remaining()`.
|
/// length between 0 and `Buf::remaining()`.
|
||||||
fn mut_bytes<'a>(&'a mut self) -> &'a mut [u8];
|
fn mut_bytes<'a>(&'a mut self) -> &'a mut [u8];
|
||||||
|
|
||||||
/// Read bytes from this Buf into the given sink and advance the cursor by
|
|
||||||
/// the number of bytes read.
|
|
||||||
fn write<S: Source>(&mut self, src: S) -> Result<usize, S::Error> {
|
|
||||||
src.fill(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Read bytes from this Buf into the given slice and advance the cursor by
|
/// Read bytes from this Buf into the given slice and advance the cursor by
|
||||||
/// the number of bytes read.
|
/// the number of bytes read.
|
||||||
///
|
///
|
||||||
@@ -164,6 +158,13 @@ pub trait MutBuf : Sized {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait MutBufExt {
|
||||||
|
|
||||||
|
/// Write bytes from the given source into the current `MutBuf` and advance
|
||||||
|
/// the cursor by the number of bytes written.
|
||||||
|
fn write<S: Source>(&mut self, src: S) -> Result<usize, S::Error>;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* ===== ByteStr =====
|
* ===== ByteStr =====
|
||||||
@@ -239,13 +240,19 @@ impl<B: Buf> BufExt for B {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<B: MutBuf> MutBufExt for B {
|
||||||
|
fn write<S: Source>(&mut self, src: S) -> Result<usize, S::Error> {
|
||||||
|
src.fill(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* ===== Sink / Source =====
|
* ===== Sink / Source =====
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// An object that reads bytes from a Buf into itself
|
/// An value that reads bytes from a Buf into itself
|
||||||
pub trait Sink {
|
pub trait Sink {
|
||||||
type Error;
|
type Error;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user