Skip to content

Instantly share code, notes, and snippets.

@sfackler
Created March 29, 2015 19:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sfackler/81f8a7ac614e19f96cc8 to your computer and use it in GitHub Desktop.
Save sfackler/81f8a7ac614e19f96cc8 to your computer and use it in GitHub Desktop.
#![feature(test, big_misc, thread_sleep, std_misc)]
extern crate test;
use std::io::prelude::*;
use std::cmp;
use std::iter;
use std::time::Duration;
use std::thread;
use std::io::{self, ErrorKind};
fn read_to_end_big<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> io::Result<usize> {
let start_len = buf.len();
let mut len = start_len;
let mut cap_bump = 16;
let ret;
loop {
if len == buf.len() {
if buf.capacity() == buf.len() {
cap_bump *= 2;
buf.reserve(cap_bump);
}
let new_area = buf.capacity() - buf.len();
buf.extend(iter::repeat(0).take(new_area));
}
match r.read(&mut buf[len..]) {
Ok(0) => {
ret = Ok(len - start_len);
break;
}
Ok(n) => len += n,
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
Err(e) => {
ret = Err(e);
break;
}
}
}
buf.truncate(len);
ret
}
fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> io::Result<usize> {
let start_len = buf.len();
let mut len = start_len;
let mut cap_bump = 16;
let ret;
loop {
if len == buf.len() {
if buf.capacity() == buf.len() {
if cap_bump < 64 * 1024 {
cap_bump *= 2;
}
buf.reserve(cap_bump);
}
let new_area = buf.capacity() - buf.len();
buf.extend(iter::repeat(0).take(new_area));
}
match r.read(&mut buf[len..]) {
Ok(0) => {
ret = Ok(len - start_len);
break;
}
Ok(n) => len += n,
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
Err(e) => {
ret = Err(e);
break;
}
}
}
buf.truncate(len);
ret
}
#[test]
fn test_new() {
let mut v = vec![1, 2, 3];
assert_eq!(Ok(5), read_to_end(&mut io::repeat(4).take(5), &mut v));
assert_eq!(vec![1, 2, 3, 4, 4, 4, 4, 4], v);
}
fn bench_big(b: &mut test::Bencher, size: u64) {
b.iter(|| {
let mut v = vec![];
read_to_end_big(&mut io::repeat(1).take(size), &mut v)
})
}
fn bench_new(b: &mut test::Bencher, size: u64) {
b.iter(|| {
let mut v = vec![];
read_to_end(&mut io::repeat(1).take(size), &mut v)
})
}
#[bench]
fn big_nodelay_4(b: &mut test::Bencher) {
bench_big(b, 4);
}
#[bench]
fn new_nodelay_4(b: &mut test::Bencher) {
bench_new(b, 4);
}
#[bench]
fn big_nodelay_50m(b: &mut test::Bencher) {
bench_big(b, 50 * 1024 * 1024);
}
#[bench]
fn new_nodelay_50m(b: &mut test::Bencher) {
bench_new(b, 50 * 1024 * 1024);
}
struct Delay<R: Read>(Duration, R);
impl<R: Read> Read for Delay<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
thread::sleep(self.0);
self.1.read(buf)
}
}
fn bench_big_delay(b: &mut test::Bencher, size: u64, delay: Duration) {
b.iter(|| {
let mut v = vec![];
read_to_end_big(&mut Delay(delay, io::repeat(1).take(size)), &mut v)
})
}
fn bench_new_delay(b: &mut test::Bencher, size: u64, delay: Duration) {
b.iter(|| {
let mut v = vec![];
read_to_end(&mut Delay(delay, io::repeat(1).take(size)), &mut v)
})
}
#[bench]
fn big_delay_4(b: &mut test::Bencher) {
bench_big_delay(b, 4, Duration::microseconds(1));
}
#[bench]
fn new_delay_4(b: &mut test::Bencher) {
bench_new_delay(b, 4, Duration::microseconds(1));
}
#[bench]
fn big_delay_50m(b: &mut test::Bencher) {
bench_big_delay(b, 50 * 1024 * 1024, Duration::microseconds(1));
}
#[bench]
fn new_delay_50m(b: &mut test::Bencher) {
bench_new_delay(b, 50 * 1024 * 1024, Duration::microseconds(1));
}
struct Cap<R: Read>(usize, R);
impl<R: Read> Read for Cap<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let end = cmp::min(buf.len(), self.0);
self.1.read(&mut buf[..end])
}
}
fn bench_big_delay_cap(b: &mut test::Bencher, size: u64, delay: Duration) {
b.iter(|| {
let mut v = vec![];
read_to_end_big(&mut Cap(10240, Delay(delay, io::repeat(1).take(size))), &mut v)
})
}
fn bench_new_delay_cap(b: &mut test::Bencher, size: u64, delay: Duration) {
b.iter(|| {
let mut v = vec![];
read_to_end(&mut Cap(10240, Delay(delay, io::repeat(1).take(size))), &mut v)
})
}
#[bench]
fn big_delay_4_cap(b: &mut test::Bencher) {
bench_big_delay_cap(b, 4, Duration::microseconds(1));
}
#[bench]
fn new_delay_4_cap(b: &mut test::Bencher) {
bench_new_delay_cap(b, 4, Duration::microseconds(1));
}
#[bench]
fn big_delay_50m_cap(b: &mut test::Bencher) {
bench_big_delay_cap(b, 50 * 1024 * 1024, Duration::microseconds(1));
}
#[bench]
fn new_delay_50m_cap(b: &mut test::Bencher) {
bench_new_delay_cap(b, 50 * 1024 * 1024, Duration::microseconds(1));
}
running 13 tests
test test_new ... ignored
test big_delay_4 ... bench: 12780 ns/iter (+/- 494)
test big_delay_4_cap ... bench: 12836 ns/iter (+/- 1723)
test big_delay_50m ... bench: 150600482 ns/iter (+/- 8506494)
test big_delay_50m_cap ... bench: 190697061 ns/iter (+/- 25702527)
test big_nodelay_4 ... bench: 93 ns/iter (+/- 1)
test big_nodelay_50m ... bench: 152458942 ns/iter (+/- 21141791)
test new_delay_4 ... bench: 13516 ns/iter (+/- 3327)
test new_delay_4_cap ... bench: 12733 ns/iter (+/- 1023)
test new_delay_50m ... bench: 151296178 ns/iter (+/- 16817833)
test new_delay_50m_cap ... bench: 190909447 ns/iter (+/- 13061688)
test new_nodelay_4 ... bench: 100 ns/iter (+/- 16)
test new_nodelay_50m ... bench: 151938291 ns/iter (+/- 5526478)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment