Skip to content

Instantly share code, notes, and snippets.

@japaric
Created November 24, 2014 14:35
Show Gist options
  • Save japaric/23c9a2e5088942492112 to your computer and use it in GitHub Desktop.
Save japaric/23c9a2e5088942492112 to your computer and use it in GitHub Desktop.
inline(always) BufWriters
#![feature(slicing_syntax)]
extern crate criterion;
use criterion::Criterion;
use std::cmp::min;
use std::io::{IoError, IoResult};
use std::raw::Repr;
use std::{io, mem, ptr, raw, slice};
const SRC_LEN: uint = 4;
const BATCHES: uint = 128;
fn main() {
Criterion::default().
//bench("never/std_vec_writer", |b| {
//let mut dst = Vec::with_capacity(BATCHES * SRC_LEN);
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//dst.clear();
//do_std_writes_inline_never(&mut dst, src, BATCHES);
//})
//}).
//bench("never/std_buf_writer", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = io::BufWriter::new(dst);
//do_std_writes_inline_never(&mut dst, src, BATCHES);
//})
//}).
//bench("never/copy_nonoverlapping", |b| {
//let dst = &mut [0_u8, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//unsafe {
//do_copy_nonoverlapping_memory_inline_never(dst.as_mut_ptr(), src.as_ptr(), src.len(), BATCHES);
//}
//})
//}).
//bench("never/slice_writer", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = dst.as_mut_slice();
//do_my_writes_inline_never(&mut dst, src, BATCHES);
//})
//}).
//bench("never/unsafe_writer", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = UnsafeWriter::new(dst);
//do_my_writes_inline_never(&mut dst, src, BATCHES);
//})
//}).
//bench("never/buf_writer_0", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = BufWriter0::new(dst);
//do_my_writes_inline_never(&mut dst, src, BATCHES);
//})
//}).
//bench("never/buf_writer_1", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = BufWriter1::new(dst);
//do_my_writes_inline_never(&mut dst, src, BATCHES);
//})
//}).
//bench("never/buf_writer_2", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = BufWriter2::new(dst);
//do_my_writes_inline_never(&mut dst, src, BATCHES);
//})
//}).
//bench("never/buf_writer_3", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = BufWriter3::new(dst);
//do_my_writes_inline_never(&mut dst, src, BATCHES);
//})
//}).
//bench("never/buf_writer_4", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = BufWriter4::new(dst);
//do_my_writes_inline_never(&mut dst, src, BATCHES);
//})
//}).
//bench("never/buf_writer_5", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = BufWriter5::new(dst);
//do_my_writes_inline_never(&mut dst, src, BATCHES);
//})
//}).
//bench("never/buf_writer_6", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = BufWriter6::new(dst);
//do_my_writes_inline_never(&mut dst, src, BATCHES);
//})
//}).
//bench("never/buf_writer_7", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = BufWriter7::new(dst);
//do_my_writes_inline_never(&mut dst, src, BATCHES);
//})
//}).
//bench("never/buf_writer_8", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = BufWriter8::new(dst);
//do_my_writes_inline_never(&mut dst, src, BATCHES);
//})
//}).
//bench("never/buf_writer_9", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = BufWriter9::new(dst);
//do_my_writes_inline_never(&mut dst, src, BATCHES);
//})
//}).
//bench("never/buf_writer_10", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = BufWriter10::new(dst);
//do_my_writes_inline_never(&mut dst, src, BATCHES);
//})
//}).
//bench("never/buf_writer_11", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = BufWriter11::new(dst);
//do_my_writes_inline_never(&mut dst, src, BATCHES);
//})
//}).
//bench("never/buf_writer_12", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = BufWriter12::new(dst);
//do_my_writes_inline_never(&mut dst, src, BATCHES);
//})
//}).
//bench("never/buf_writer_13", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = BufWriter13::new(dst);
//do_my_writes_inline_never(&mut dst, src, BATCHES);
//})
//}).
//bench("never/vec_writer_1", |b| {
//let mut dst = Vec::with_capacity(BATCHES * SRC_LEN);
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//dst.clear();
//let mut dst = VecWriter1::new(&mut dst);
//do_my_writes_inline_never(&mut dst, src, BATCHES);
//})
//}).
//summarize("never").
bench("always/std_vec_writer", |b| {
let mut dst = Vec::with_capacity(BATCHES * SRC_LEN);
let src = &[1, .. SRC_LEN];
b.iter(|| {
dst.clear();
do_std_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/std_buf_writer", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = io::BufWriter::new(dst);
do_std_writes_inline_always(&mut dst, src, BATCHES);
})
}).
//bench("always/copy_nonoverlapping", |b| {
//let dst = &mut [0_u8, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//unsafe {
//do_copy_nonoverlapping_memory_inline_always(dst.as_mut_ptr(), src.as_ptr(), src.len(), BATCHES);
//}
//})
//}).
bench("always/slice_writer", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = dst.as_mut_slice();
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
//bench("always/unsafe_writer", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = UnsafeWriter::new(dst);
//do_my_writes_inline_always(&mut dst, src, BATCHES);
//})
//}).
bench("always/buf_writer_0", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter0::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_1", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter1::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_2", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter2::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_3", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter3::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_4", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter4::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_5", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter5::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_6", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter6::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
//bench("always/buf_writer_7", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = BufWriter7::new(dst);
//do_my_writes_inline_always(&mut dst, src, BATCHES);
//})
//}).
bench("always/buf_writer_8", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter8::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_9", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter9::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_10", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter10::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_11", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter11::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_12", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter12::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_13", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter13::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/vec_writer_1", |b| {
let mut dst = Vec::with_capacity(BATCHES * SRC_LEN);
let src = &[1, .. SRC_LEN];
b.iter(|| {
dst.clear();
let mut dst = VecWriter1::new(&mut dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
summarize("always");
}
#[inline(never)]
fn do_std_writes_inline_never<W: Writer>(dst: &mut W, src: &[u8], batches: uint) {
for _ in range(0, batches) {
dst.write(src).unwrap();
}
}
#[inline(never)]
unsafe fn do_copy_nonoverlapping_memory_inline_never(mut dst: *mut u8, src: *const u8, len: uint, batches: uint) {
for _ in range(0, batches) {
ptr::copy_nonoverlapping_memory(dst, src, len);
dst = dst.offset(len as int);
}
}
trait MyWriter {
fn my_write(&mut self, src: &[u8]) -> IoResult<()>;
}
#[inline(never)]
fn do_my_writes_inline_never<W>(dst: &mut W, src: &[u8], batches: uint) where W: MyWriter {
for _ in range(0, batches) {
dst.my_write(src).unwrap();
}
}
#[inline(always)]
fn do_std_writes_inline_always<W: Writer>(dst: &mut W, src: &[u8], batches: uint) {
for _ in range(0, batches) {
dst.write(src).unwrap();
}
}
#[inline(always)]
fn do_my_writes_inline_always<W>(dst: &mut W, src: &[u8], batches: uint) where W: MyWriter {
for _ in range(0, batches) {
dst.my_write(src).unwrap();
}
}
#[inline(always)]
unsafe fn do_copy_nonoverlapping_memory_inline_always(mut dst: *mut u8, src: *const u8, len: uint, batches: uint) {
for _ in range(0, batches) {
ptr::copy_nonoverlapping_memory(dst, src, len);
dst = dst.offset(len as int);
}
}
impl<'a> MyWriter for &'a mut [u8] {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
if self.is_empty() { return Err(io::standard_error(io::EndOfFile)); }
let dst_len = self.len();
let src_len = src.len();
let write_len = min(dst_len, src_len);
slice::bytes::copy_memory(*self, src.slice_to(write_len));
unsafe {
*self = mem::transmute(raw::Slice {
data: self.as_ptr().offset(write_len as int),
len: dst_len - write_len,
});
}
if src_len > dst_len {
Err(io::standard_error(io::ShortWrite(write_len)))
} else {
Ok(())
}
}
}
struct UnsafeWriter<'a> {
dst: *mut u8,
}
impl<'a> UnsafeWriter<'a> {
#[inline]
fn new(dst: &'a mut [u8]) -> UnsafeWriter<'a> {
UnsafeWriter {
dst: dst.as_mut_ptr(),
}
}
}
impl<'a> MyWriter for UnsafeWriter<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let len = src.len();
unsafe {
ptr::copy_nonoverlapping_memory(self.dst, src.as_ptr(), len);
self.dst = self.dst.offset(len as int);
}
Ok(())
}
}
struct BufWriter0<'a> {
dst: &'a mut [u8],
}
impl<'a> BufWriter0<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter0<'a> {
BufWriter0 {
dst: dst
}
}
}
impl<'a> MyWriter for BufWriter0<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
if self.dst.is_empty() { return Err(io::standard_error(io::EndOfFile)); }
let dst_len = self.dst.len();
let src_len = src.len();
let write_len = min(dst_len, src_len);
slice::bytes::copy_memory(self.dst, src.slice_to(write_len));
unsafe {
self.dst = mem::transmute(raw::Slice {
data: self.dst.as_ptr().offset(write_len as int),
len: dst_len - write_len,
});
}
if src_len > dst_len {
Err(io::standard_error(io::ShortWrite(write_len)))
} else {
Ok(())
}
}
}
struct BufWriter1<'a> {
dst: &'a mut [u8],
}
impl<'a> BufWriter1<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter1<'a> {
BufWriter1 {
dst: dst,
}
}
}
impl<'a> MyWriter for BufWriter1<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let dst_len = self.dst.len();
let src_len = src.len();
let write_len = min(dst_len, src_len);
slice::bytes::copy_memory(self.dst, src[..write_len]);
unsafe {
let self_: &mut raw::Slice<u8> = mem::transmute(self);
self_.data = self_.data.offset(write_len as int);
self_.len = dst_len - write_len;
}
Ok(())
}
}
struct BufWriter2<'a> {
dst: &'a mut [u8],
}
impl<'a> BufWriter2<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter2<'a> {
BufWriter2 {
dst: dst,
}
}
}
impl<'a> MyWriter for BufWriter2<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let dst_len = self.dst.len();
let write_len = src.len();
slice::bytes::copy_memory(self.dst, src[..write_len]);
unsafe {
let self_: &mut raw::Slice<u8> = mem::transmute(self);
self_.data = self_.data.offset(write_len as int);
self_.len = dst_len - write_len;
}
Ok(())
}
}
struct BufWriter3<'a> {
dst: &'a mut [u8],
pos: uint,
}
impl<'a> BufWriter3<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter3<'a> {
BufWriter3 {
dst: dst,
pos: 0,
}
}
}
impl<'a> MyWriter for BufWriter3<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
// return an error if the entire write does not fit in the buffer
let cap = if self.pos >= self.dst.len() { 0 } else { self.dst.len() - self.pos };
if src.len() > cap {
return Err(IoError {
kind: io::OtherIoError,
desc: "Trying to write past end of buffer",
detail: None
})
}
slice::bytes::copy_memory(self.dst[mut self.pos..], src);
self.pos += src.len();
Ok(())
}
}
struct BufWriter4<'a> {
dst: *mut u8,
end: *mut u8,
}
impl<'a> BufWriter4<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter4<'a> {
let dst_ptr = dst.as_mut_ptr();
unsafe {
BufWriter4 {
dst: dst_ptr,
end: dst_ptr.offset(dst.len() as int),
}
}
}
#[inline]
fn capacity(&self) -> uint {
self.end as uint - self.dst as uint
}
}
impl<'a> MyWriter for BufWriter4<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let src_len = src.len();
if src_len > self.capacity() {
return Err(IoError {
kind: io::OtherIoError,
desc: "Trying to write past end of buffer",
detail: None
})
}
unsafe {
ptr::copy_nonoverlapping_memory(self.dst, src.as_ptr(), src_len);
self.dst = self.dst.offset(src_len as int);
}
Ok(())
}
}
struct BufWriter5<'a> {
dst: &'a mut [u8],
}
impl<'a> BufWriter5<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter5<'a> {
BufWriter5 {
dst: dst,
}
}
}
impl<'a> MyWriter for BufWriter5<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let dst_len = self.dst.len();
let src_len = src.len();
let x = (dst_len < src_len) as uint;
let write_len = dst_len * x + src_len * (1 - x);
slice::bytes::copy_memory(self.dst, src[..write_len]);
unsafe {
let self_: &mut raw::Slice<u8> = mem::transmute(self);
self_.data = self_.data.offset(write_len as int);
self_.len = dst_len - write_len;
}
Ok(())
}
}
struct BufWriter6<'a> {
dst: &'a mut [u8],
}
impl<'a> BufWriter6<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter6<'a> {
BufWriter6 {
dst: dst,
}
}
}
impl<'a> MyWriter for BufWriter6<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let dst_len = self.dst.len();
let src_len = src.len();
let write_len = min(dst_len, src_len);
unsafe {
ptr::copy_nonoverlapping_memory(
self.dst.as_mut_ptr(),
src.as_ptr(),
write_len);
let self_: &mut raw::Slice<u8> = mem::transmute(self);
self_.data = self_.data.offset(write_len as int);
self_.len = dst_len - write_len;
}
Ok(())
}
}
struct BufWriter7<'a> {
dst: &'a mut [u8],
pos: uint,
}
impl<'a> BufWriter7<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter7<'a> {
BufWriter7 {
dst: dst,
pos: 0,
}
}
}
impl<'a> MyWriter for BufWriter7<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
// return an error if the entire write does not fit in the buffer
let dst_len = self.dst.len();
let src_len = src.len();
let cap = if self.pos >= dst_len { 0 } else { dst_len - self.pos };
if src_len > cap {
return Err(IoError {
kind: io::OtherIoError,
desc: "Trying to write past end of buffer",
detail: None
})
}
unsafe {
ptr::copy_nonoverlapping_memory(
self.dst.as_mut_ptr().offset(self.pos as int),
src.as_ptr(),
src_len);
}
self.pos += src_len;
Ok(())
}
}
struct BufWriter8<'a> {
dst: *mut u8,
end: *mut u8,
}
impl<'a> BufWriter8<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter8<'a> {
let dst_ptr = dst.as_mut_ptr();
unsafe {
BufWriter8 {
dst: dst_ptr,
end: dst_ptr.offset(dst.len() as int),
}
}
}
}
impl<'a> MyWriter for BufWriter8<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let src_len = src.len();
let cap = self.end as uint - self.dst as uint;
if src_len > cap {
return Err(IoError {
kind: io::OtherIoError,
desc: "Trying to write past end of buffer",
detail: None
})
}
unsafe {
ptr::copy_nonoverlapping_memory(self.dst, src.as_ptr(), src_len);
self.dst = self.dst.offset(src_len as int);
}
Ok(())
}
}
struct BufWriter9<'a> {
dst: *mut u8,
end: *mut u8,
}
impl<'a> BufWriter9<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter9<'a> {
let dst_ptr = dst.as_mut_ptr();
unsafe {
BufWriter9 {
dst: dst_ptr,
end: dst_ptr.offset(dst.len() as int),
}
}
}
}
impl<'a> MyWriter for BufWriter9<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
unsafe {
let raw::Slice { data: src_ptr, len: src_len } = src.repr();
let cap = self.end as uint - self.dst as uint;
if src_len > cap {
return Err(IoError {
kind: io::OtherIoError,
desc: "Trying to write past end of buffer",
detail: None
})
}
ptr::copy_nonoverlapping_memory(self.dst, src_ptr, src_len);
self.dst = self.dst.offset(src_len as int);
}
Ok(())
}
}
struct BufWriter10<'a> {
dst: &'a mut [u8],
pos: uint,
}
impl<'a> BufWriter10<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter10<'a> {
BufWriter10 {
dst: dst,
pos: 0,
}
}
}
impl<'a> MyWriter for BufWriter10<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let dst_len = self.dst.len();
let src_len = src.len();
if self.pos == dst_len { return Err(io::standard_error(io::EndOfFile)); }
let cap = dst_len - self.pos;
let write_len = min(cap, src_len);
slice::bytes::copy_memory(self.dst[mut self.pos..], src[..write_len]);
if src_len > dst_len {
return Err(io::standard_error(io::ShortWrite(write_len)));
}
self.pos += write_len;
Ok(())
}
}
struct BufWriter11<'a> {
dst: &'a mut [u8],
pos: uint,
}
impl<'a> BufWriter11<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter11<'a> {
BufWriter11 {
dst: dst,
pos: 0,
}
}
}
impl<'a> MyWriter for BufWriter11<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let dst = self.dst[mut self.pos..];
let dst_len = dst.len();
if dst_len == 0 {
return Err(io::standard_error(io::EndOfFile));
}
let src_len = src.len();
if dst_len >= src_len {
unsafe {
ptr::copy_nonoverlapping_memory(
dst.as_mut_ptr(),
src.as_ptr(),
src_len);
}
self.pos += src_len;
Ok(())
} else {
unsafe {
ptr::copy_nonoverlapping_memory(
dst.as_mut_ptr(),
src.as_ptr(),
dst_len);
}
self.pos += dst_len;
Err(io::standard_error(io::ShortWrite(dst_len)))
}
}
}
struct BufWriter12<'a> {
dst: &'a mut [u8],
}
impl<'a> BufWriter12<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter12<'a> {
BufWriter12 {
dst: dst,
}
}
}
impl<'a> MyWriter for BufWriter12<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let dst_len = self.dst.len();
if dst_len == 0 {
return Err(io::standard_error(io::EndOfFile));
}
let src_len = src.len();
if dst_len >= src_len {
unsafe {
ptr::copy_nonoverlapping_memory(
self.dst.as_mut_ptr(),
src.as_ptr(),
src_len);
self.dst = mem::transmute(raw::Slice {
data: self.dst.as_ptr().offset(src_len as int),
len: dst_len - src_len,
});
}
Ok(())
} else {
unsafe {
ptr::copy_nonoverlapping_memory(
self.dst.as_mut_ptr(),
src.as_ptr(),
dst_len);
self.dst = mem::transmute(raw::Slice {
data: self.dst.as_ptr().offset(dst_len as int),
len: 0,
});
}
Err(io::standard_error(io::ShortWrite(dst_len)))
}
}
}
struct BufWriter13<'a> {
dst: *mut u8,
end: *mut u8,
}
impl<'a> BufWriter13<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter13<'a> {
let dst_ptr = dst.as_mut_ptr();
unsafe {
BufWriter13 {
dst: dst_ptr,
end: dst_ptr.offset(dst.len() as int),
}
}
}
}
impl<'a> MyWriter for BufWriter13<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let dst_len = self.end as uint - self.dst as uint;
if dst_len == 0 {
return Err(io::standard_error(io::EndOfFile));
}
let src_len = src.len();
if dst_len >= src_len {
unsafe {
ptr::copy_nonoverlapping_memory(
self.dst,
src.as_ptr(),
src_len);
self.dst = self.dst.offset(src_len as int);
}
Ok(())
} else {
unsafe {
ptr::copy_nonoverlapping_memory(
self.dst,
src.as_ptr(),
dst_len);
self.dst = self.dst.offset(dst_len as int);
}
Err(io::standard_error(io::ShortWrite(dst_len)))
}
}
}
struct VecWriter1<'a> {
dst: &'a mut Vec<u8>,
}
impl<'a> VecWriter1<'a> {
#[inline]
fn new<'a>(dst: &'a mut Vec<u8>) -> VecWriter1<'a> {
VecWriter1 {
dst: dst,
}
}
}
impl<'a> MyWriter for VecWriter1<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let src_len = src.len();
self.dst.reserve(src_len);
let dst = self.dst.as_mut_slice();
unsafe {
// we reserved enough room in `dst` to store `src`.
ptr::copy_nonoverlapping_memory(
dst.as_mut_ptr(),
src.as_ptr(),
src_len);
}
Ok(())
}
}
$ cargo run --release
Benchmarking always/std_vec_writer
> Warming up for 3.0000 s
> Collecting 100 samples in estimated 5.0013 s
> Found 9 outliers among 100 measurements (9.00%)
> 4 (4.00%) high mild
> 5 (5.00%) high severe
> Performing linear regression
> slope [897.80 ns 901.12 ns]
> R^2 0.9997734 0.9997631
> Estimating the statistics of the sample
> mean [897.97 ns 907.89 ns]
> median [897.50 ns 898.07 ns]
> MAD [1.0593 ns 2.0182 ns]
> SD [2.2779 ns 48.961 ns]
Benchmarking always/std_buf_writer
> Warming up for 3.0000 s
> Collecting 100 samples in estimated 5.0032 s
> Found 11 outliers among 100 measurements (11.00%)
> 1 (1.00%) low mild
> 4 (4.00%) high mild
> 6 (6.00%) high severe
> Performing linear regression
> slope [732.76 ns 734.03 ns]
> R^2 0.9998321 0.9998291
> Estimating the statistics of the sample
> mean [733.21 ns 738.23 ns]
> median [732.57 ns 733.14 ns]
> MAD [824.66 ps 1.5828 ns]
> SD [2.0385 ns 20.858 ns]
Benchmarking always/slice_writer
> Warming up for 3.0000 s
> Collecting 100 samples in estimated 5.0020 s
> Found 10 outliers among 100 measurements (10.00%)
> 4 (4.00%) high mild
> 6 (6.00%) high severe
> Performing linear regression
> slope [776.20 ns 778.68 ns]
> R^2 0.9998526 0.9998483
> Estimating the statistics of the sample
> mean [776.42 ns 780.14 ns]
> median [775.01 ns 776.18 ns]
> MAD [1.5978 ns 2.7767 ns]
> SD [3.9519 ns 14.650 ns]
Benchmarking always/buf_writer_0
> Warming up for 3.0000 s
> Collecting 100 samples in estimated 5.0029 s
> Found 12 outliers among 100 measurements (12.00%)
> 4 (4.00%) high mild
> 8 (8.00%) high severe
> Performing linear regression
> slope [776.80 ns 779.54 ns]
> R^2 0.9997851 0.9997802
> Estimating the statistics of the sample
> mean [777.03 ns 780.22 ns]
> median [775.25 ns 776.47 ns]
> MAD [1.5863 ns 3.2366 ns]
> SD [4.6757 ns 11.667 ns]
Benchmarking always/buf_writer_1
> Warming up for 3.0000 s
> Collecting 100 samples in estimated 5.0014 s
> Found 11 outliers among 100 measurements (11.00%)
> 3 (3.00%) high mild
> 8 (8.00%) high severe
> Performing linear regression
> slope [368.67 ns 369.34 ns]
> R^2 0.9999342 0.9999322
> Estimating the statistics of the sample
> mean [369.11 ns 377.39 ns]
> median [368.52 ns 368.87 ns]
> MAD [527.06 ps 892.94 ps]
> SD [2.1251 ns 40.065 ns]
Benchmarking always/buf_writer_2
> Warming up for 3.0000 s
> Collecting 100 samples in estimated 5.0001 s
> Found 4 outliers among 100 measurements (4.00%)
> 1 (1.00%) high mild
> 3 (3.00%) high severe
> Performing linear regression
> slope [50.082 ns 50.269 ns]
> R^2 0.9997409 0.9997402
> Estimating the statistics of the sample
> mean [50.278 ns 50.592 ns]
> median [50.121 ns 50.373 ns]
> MAD [353.50 ps 570.45 ps]
> SD [508.74 ps 1.0633 ns]
Benchmarking always/buf_writer_3
> Warming up for 3.0000 s
> Collecting 100 samples in estimated 5.0013 s
> Found 14 outliers among 100 measurements (14.00%)
> 4 (4.00%) high mild
> 10 (10.00%) high severe
> Performing linear regression
> slope [732.83 ns 734.00 ns]
> R^2 0.9999259 0.9999246
> Estimating the statistics of the sample
> mean [733.78 ns 753.76 ns]
> median [732.45 ns 732.91 ns]
> MAD [798.84 ps 1.5091 ns]
> SD [4.5788 ns 101.82 ns]
Benchmarking always/buf_writer_4
> Warming up for 3.0000 s
> Collecting 100 samples in estimated 5.0002 s
> Found 13 outliers among 100 measurements (13.00%)
> 5 (5.00%) high mild
> 8 (8.00%) high severe
> Performing linear regression
> slope [100.26 ns 100.58 ns]
> R^2 0.9998730 0.9998691
> Estimating the statistics of the sample
> mean [100.41 ns 100.97 ns]
> median [100.14 ns 100.27 ns]
> MAD [160.08 ps 374.14 ps]
> SD [707.75 ps 2.0544 ns]
Benchmarking always/buf_writer_5
> Warming up for 3.0000 s
> Collecting 100 samples in estimated 5.0017 s
> Found 7 outliers among 100 measurements (7.00%)
> 2 (2.00%) high mild
> 5 (5.00%) high severe
> Performing linear regression
> slope [414.90 ns 415.62 ns]
> R^2 0.9999358 0.9999356
> Estimating the statistics of the sample
> mean [415.44 ns 418.65 ns]
> median [414.26 ns 415.91 ns]
> MAD [1.4870 ns 2.9297 ns]
> SD [2.8660 ns 13.227 ns]
Benchmarking always/buf_writer_6
> Warming up for 3.0000 s
> Collecting 100 samples in estimated 5.0010 s
> Found 6 outliers among 100 measurements (6.00%)
> 5 (5.00%) high mild
> 1 (1.00%) high severe
> Performing linear regression
> slope [369.64 ns 370.82 ns]
> R^2 0.9998496 0.9998468
> Estimating the statistics of the sample
> mean [369.60 ns 370.88 ns]
> median [368.90 ns 369.71 ns]
> MAD [980.33 ps 1.9745 ns]
> SD [1.7933 ns 4.9335 ns]
Benchmarking always/buf_writer_8
> Warming up for 3.0000 s
> Collecting 100 samples in estimated 5.0005 s
> Found 12 outliers among 100 measurements (12.00%)
> 6 (6.00%) high mild
> 6 (6.00%) high severe
> Performing linear regression
> slope [100.50 ns 100.98 ns]
> R^2 0.9993988 0.9993908
> Estimating the statistics of the sample
> mean [100.82 ns 101.61 ns]
> median [100.18 ns 100.46 ns]
> MAD [257.96 ps 616.39 ps]
> SD [1.3931 ns 2.6183 ns]
Benchmarking always/buf_writer_9
> Warming up for 3.0000 s
> Collecting 100 samples in estimated 5.0002 s
> Found 3 outliers among 100 measurements (3.00%)
> 3 (3.00%) high mild
> Performing linear regression
> slope [101.31 ns 102.35 ns]
> R^2 0.9980303 0.9979736
> Estimating the statistics of the sample
> mean [102.48 ns 103.61 ns]
> median [100.98 ns 103.06 ns]
> MAD [839.04 ps 3.5579 ns]
> SD [2.4141 ns 3.3523 ns]
Benchmarking always/buf_writer_10
> Warming up for 3.0000 s
> Collecting 100 samples in estimated 5.0015 s
> Found 8 outliers among 100 measurements (8.00%)
> 2 (2.00%) low mild
> 1 (1.00%) high mild
> 5 (5.00%) high severe
> Performing linear regression
> slope [794.26 ns 797.64 ns]
> R^2 0.9997195 0.9997095
> Estimating the statistics of the sample
> mean [794.70 ns 797.72 ns]
> median [793.96 ns 795.39 ns]
> MAD [3.3684 ns 5.5165 ns]
> SD [5.4863 ns 9.8771 ns]
Benchmarking always/buf_writer_11
> Warming up for 3.0000 s
> Collecting 100 samples in estimated 5.0020 s
> Found 4 outliers among 100 measurements (4.00%)
> 4 (4.00%) high severe
> Performing linear regression
> slope [738.00 ns 739.39 ns]
> R^2 0.9999384 0.9999382
> Estimating the statistics of the sample
> mean [738.00 ns 743.09 ns]
> median [736.82 ns 739.01 ns]
> MAD [2.5983 ns 3.9555 ns]
> SD [3.1995 ns 22.607 ns]
Benchmarking always/buf_writer_12
> Warming up for 3.0000 s
> Collecting 100 samples in estimated 5.0014 s
> Found 7 outliers among 100 measurements (7.00%)
> 3 (3.00%) high mild
> 4 (4.00%) high severe
> Performing linear regression
> slope [737.16 ns 738.55 ns]
> R^2 0.9999238 0.9999233
> Estimating the statistics of the sample
> mean [738.03 ns 742.04 ns]
> median [736.55 ns 738.52 ns]
> MAD [2.5274 ns 4.0878 ns]
> SD [3.8891 ns 14.786 ns]
Benchmarking always/buf_writer_13
> Warming up for 3.0000 s
> Collecting 100 samples in estimated 5.0001 s
> Found 6 outliers among 100 measurements (6.00%)
> 3 (3.00%) high mild
> 3 (3.00%) high severe
> Performing linear regression
> slope [697.66 ns 700.05 ns]
> R^2 0.9998245 0.9998206
> Estimating the statistics of the sample
> mean [697.61 ns 701.89 ns]
> median [696.03 ns 698.02 ns]
> MAD [1.9839 ns 3.9714 ns]
> SD [3.5975 ns 17.922 ns]
Benchmarking always/vec_writer_1
> Warming up for 3.0000 s
> Collecting 100 samples in estimated 5.0002 s
> Found 15 outliers among 100 measurements (15.00%)
> 8 (8.00%) high mild
> 7 (7.00%) high severe
> Performing linear regression
> slope [57.501 ns 57.724 ns]
> R^2 0.9995761 0.9995701
> Estimating the statistics of the sample
> mean [57.709 ns 58.138 ns]
> median [57.414 ns 57.559 ns]
> MAD [188.51 ps 417.01 ps]
> SD [691.72 ps 1.4572 ns]
Summarizing results of always... DONE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment