Created
March 13, 2015 07:33
-
-
Save anonymous/74506f7daa102b6fa32b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate test; | |
use std::io::prelude::*; | |
use std::io; | |
use std::mem; | |
use std::cmp; | |
use std::slice; | |
struct MyBufWriter1<'a> { | |
buf: &'a mut [u8], | |
} | |
impl<'a> MyBufWriter1<'a> { | |
pub fn new(buf: &'a mut [u8]) -> MyBufWriter1<'a> { | |
MyBufWriter1 { | |
buf: buf, | |
} | |
} | |
} | |
impl<'a> io::Write for MyBufWriter1<'a> { | |
#[inline] | |
fn write(&mut self, data: &[u8]) -> io::Result<usize> { | |
let amt = cmp::min(data.len(), self.buf.len()); | |
let (a, b) = mem::replace(&mut self.buf, &mut []).split_at_mut(amt); | |
slice::bytes::copy_memory(a, &data[..amt]); | |
self.buf = b; | |
Ok(amt) | |
} | |
#[inline] | |
fn write_all(&mut self, data: &[u8]) -> io::Result<()> { | |
if try!(self.write(data)) == data.len() { | |
Ok(()) | |
} else { | |
Err(io::Error::new(io::ErrorKind::WriteZero, "failed to write whole buffer", None)) | |
} | |
} | |
#[inline] | |
fn flush(&mut self) -> io::Result<()> { Ok(()) } | |
} | |
struct MyBufWriter2<'a> { | |
dst: &'a mut [u8], | |
} | |
impl<'a> MyBufWriter2<'a> { | |
pub fn new(buf: &'a mut [u8]) -> MyBufWriter2<'a> { | |
MyBufWriter2 { | |
dst: buf, | |
} | |
} | |
} | |
impl<'a> io::Write for MyBufWriter2<'a> { | |
fn write(&mut self, _data: &[u8]) -> io::Result<usize> { | |
panic!() | |
} | |
fn write_all(&mut self, src: &[u8]) -> io::Result<()> { | |
use std::raw; | |
use std::ptr; | |
let dst_len = self.dst.len(); | |
if dst_len == 0 { | |
return Err(io::Error::new(io::ErrorKind::WriteZero, "failed to write whole buffer", None)); | |
} | |
let src_len = src.len(); | |
if dst_len >= src_len { | |
unsafe { | |
ptr::copy_nonoverlapping( | |
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 isize), | |
len: dst_len - src_len, | |
}); | |
} | |
Ok(()) | |
} else { | |
unsafe { | |
ptr::copy_nonoverlapping( | |
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 isize), | |
len: 0, | |
}); | |
} | |
Err(io::Error::new(io::ErrorKind::WriteZero, "failed to write whole buffer", None)) | |
} | |
} | |
fn flush(&mut self) -> io::Result<()> { Ok(()) } | |
} | |
static DATA: [u8; 1 * 1024] = [1; 1 * 1024]; | |
#[inline(never)] | |
fn bh<W: Write>(w: &mut W) { | |
for _ in 0..64 { | |
w.write_all(&DATA).unwrap(); | |
} | |
} | |
#[bench] | |
fn b1(b: &mut test::Bencher) { | |
let mut a = [0; 64 * 1024]; | |
b.iter(|| { | |
bh(&mut MyBufWriter1::new(&mut a[..])) | |
}); | |
b.bytes = a.len() as u64; | |
} | |
#[bench] | |
fn b2(b: &mut test::Bencher) { | |
let mut a = [0; 64 * 1024]; | |
b.iter(|| { | |
bh(&mut MyBufWriter2::new(&mut a[..])) | |
}); | |
b.bytes = a.len() as u64; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment