From 84f307643811f5eb6fb85facc603a16eb7c3eaa0 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Tue, 30 Jan 2018 14:58:51 -0800 Subject: [PATCH] perf(client): don't make a copy of Headers each Request --- src/client/mod.rs | 14 ++++++++------ src/header/internals/vec_map.rs | 5 +++++ src/header/mod.rs | 8 ++++++++ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/client/mod.rs b/src/client/mod.rs index dec8a91d..509dd564 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -14,7 +14,7 @@ use http; use tokio::reactor::Handle; pub use tokio_service::Service; -use header::{Headers, Host}; +use header::{Host}; use proto; use proto::request; use method::Method; @@ -180,12 +180,14 @@ where C: Connect, )))); } }; - let host = Host::new(domain.host().expect("authority implies host").to_owned(), domain.port()); let (mut head, body) = request::split(req); - let mut headers = Headers::new(); - headers.set(host); - headers.extend(head.headers.iter()); - head.headers = headers; + if !head.headers.has::() { + let host = Host::new( + domain.host().expect("authority implies host").to_owned(), + domain.port(), + ); + head.headers.set_pos(0, host); + } use futures::Sink; use futures::sync::{mpsc, oneshot}; diff --git a/src/header/internals/vec_map.rs b/src/header/internals/vec_map.rs index a1e70d54..8ddc6a5a 100644 --- a/src/header/internals/vec_map.rs +++ b/src/header/internals/vec_map.rs @@ -23,6 +23,11 @@ impl VecMap { self.vec.push((key, value)); } + pub fn insert_pos(&mut self, key: K, value: V, pos: usize) { + debug_assert!(!self.contains_key(&key)); + self.vec.insert(pos, (key, value)) + } + #[inline] pub fn append(&mut self, key: K, value: V) { self.vec.push((key, value)); diff --git a/src/header/mod.rs b/src/header/mod.rs index 0dc3a30b..866d2521 100644 --- a/src/header/mod.rs +++ b/src/header/mod.rs @@ -392,6 +392,14 @@ impl Headers { Item::new_typed(value)); } + pub(crate) fn set_pos(&mut self, pos: usize, value: H) { + self.data.insert_pos( + HeaderName(Ascii::new(Cow::Borrowed(header_name::()))), + Item::new_typed(value), + pos, + ); + } + /// Get a reference to the header field's value, if it exists. pub fn get(&self) -> Option<&H> { self.data.get(&HeaderName(Ascii::new(Cow::Borrowed(header_name::()))))