perf(h1): use faster flattening of body buffers
This commit is contained in:
		| @@ -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); | ||||||
|  |             } | ||||||
|  |         }) | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user