perf(h1): use faster flattening of body buffers

This commit is contained in:
Sean McArthur
2018-06-03 16:19:24 -07:00
parent beace2f31e
commit 185432da1b

View File

@@ -338,12 +338,24 @@ where
WriteBufAuto::new(self) WriteBufAuto::new(self)
} }
pub(super) fn buffer<BB: Buf + Into<B>>(&mut self, buf: BB) { pub(super) fn buffer<BB: Buf + Into<B>>(&mut self, mut buf: BB) {
debug_assert!(buf.has_remaining()); debug_assert!(buf.has_remaining());
match self.strategy { match self.strategy {
Strategy::Flatten => { Strategy::Flatten => {
let head = self.headers_mut(); let head = self.headers_mut();
head.bytes.put(buf); //perf: This is a little faster than <Vec as BufMut>>::put,
//but accomplishes the same result.
loop {
let adv = {
let slice = buf.bytes();
if slice.is_empty() {
return;
}
head.bytes.extend_from_slice(slice);
slice.len()
};
buf.advance(adv);
}
}, },
Strategy::Auto | Strategy::Queue => { Strategy::Auto | Strategy::Queue => {
self.queue.bufs.push_back(buf.into()); self.queue.bufs.push_back(buf.into());
@@ -548,6 +560,9 @@ mod tests {
use std::io::Read; use std::io::Read;
use mock::AsyncIo; use mock::AsyncIo;
#[cfg(feature = "nightly")]
use test::Bencher;
#[cfg(test)] #[cfg(test)]
impl<T: Read> MemRead for ::mock::AsyncIo<T> { impl<T: Read> MemRead for ::mock::AsyncIo<T> {
fn read_mem(&mut self, len: usize) -> Poll<Bytes, io::Error> { fn read_mem(&mut self, len: usize) -> Poll<Bytes, io::Error> {
@@ -684,4 +699,22 @@ mod tests {
assert_eq!(buffered.io.num_writes(), 4); assert_eq!(buffered.io.num_writes(), 4);
assert_eq!(buffered.write_buf.queue.bufs.len(), 0); assert_eq!(buffered.write_buf.queue.bufs.len(), 0);
} }
#[cfg(feature = "nightly")]
#[bench]
fn bench_write_buf_flatten_buffer_chunk(b: &mut Bencher) {
let s = "Hello, World!";
b.bytes = s.len() as u64;
let mut write_buf = WriteBuf::<::Chunk>::new();
write_buf.set_strategy(Strategy::Flatten);
b.iter(|| {
let chunk = ::Chunk::from(s);
write_buf.buffer(chunk);
::test::black_box(&write_buf);
unsafe {
write_buf.headers.bytes.set_len(0);
}
})
}
} }