Created
March 29, 2015 19:22
-
-
Save sfackler/81f8a7ac614e19f96cc8 to your computer and use it in GitHub Desktop.
This file contains 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
#![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)); | |
} |
This file contains 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
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