perf(http1): implement an adaptive read buffer strategy

The default read strategy for HTTP/1 connections is now adaptive. It
increases or decreases the size of the read buffer depending on the
number of bytes that are received in a `read` call. If a transport
continuously fills the read buffer, it will continue to grow (up to the
`max_buf_size`), allowing for reading faster. If the transport
consistently only fills a portion of the read buffer, it will be shrunk.

This doesn't provide much benefit to small requests/responses, but
benchmarks show it to be a noticeable improvement to throughput when
streaming larger bodies.

Closes #1708
This commit is contained in:
Sean McArthur
2018-11-27 16:16:58 -08:00
parent a6fff13a39
commit fd25129dc0
2 changed files with 202 additions and 29 deletions

View File

@@ -29,6 +29,26 @@ fn http1_post(b: &mut test::Bencher) {
.bench(b)
}
#[bench]
fn http1_body_100kb(b: &mut test::Bencher) {
let body = &[b'x'; 1024 * 100];
opts()
.method(Method::POST)
.request_body(body)
.response_body(body)
.bench(b)
}
#[bench]
fn http1_body_10mb(b: &mut test::Bencher) {
let body = &[b'x'; 1024 * 1024 * 10];
opts()
.method(Method::POST)
.request_body(body)
.response_body(body)
.bench(b)
}
#[bench]
fn http1_get_parallel(b: &mut test::Bencher) {
opts()
@@ -96,6 +116,11 @@ impl Opts {
self
}
fn response_body(mut self, body: &'static [u8]) -> Self {
self.response_body = body;
self
}
fn parallel(mut self, cnt: u32) -> Self {
assert!(cnt > 0, "parallel count must be larger than 0");
self.parallel_cnt = cnt;
@@ -105,6 +130,9 @@ impl Opts {
fn bench(self, b: &mut test::Bencher) {
let _ = pretty_env_logger::try_init();
let mut rt = Runtime::new().unwrap();
b.bytes = self.response_body.len() as u64 + self.request_body.map(|b| b.len()).unwrap_or(0) as u64;
let addr = spawn_hello(&mut rt, self.response_body);
let connector = HttpConnector::new(1);