perf(header): optimize when inserting a new type header
This commit is contained in:
@@ -58,6 +58,11 @@ impl<V: ?Sized + Any + 'static> PtrMapCell<V> {
|
|||||||
PtrMapCell(UnsafeCell::new(PtrMap::Empty))
|
PtrMapCell(UnsafeCell::new(PtrMap::Empty))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn with_one(key: TypeId, val: Box<V>) -> PtrMapCell<V> {
|
||||||
|
PtrMapCell(UnsafeCell::new(PtrMap::One(key, val)))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get(&self, key: TypeId) -> Option<&V> {
|
pub fn get(&self, key: TypeId) -> Option<&V> {
|
||||||
let map = unsafe { &*self.0.get() };
|
let map = unsafe { &*self.0.get() };
|
||||||
|
|||||||
@@ -23,12 +23,11 @@ impl Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_typed(ty: Box<Header + Send + Sync>) -> Item {
|
|
||||||
let map = PtrMapCell::new();
|
pub fn new_typed<H: Header>(val: H) -> Item {
|
||||||
unsafe { map.insert((*ty).get_type(), ty); }
|
|
||||||
Item {
|
Item {
|
||||||
raw: OptCell::new(None),
|
raw: OptCell::new(None),
|
||||||
typed: map,
|
typed: PtrMapCell::with_one(TypeId::of::<H>(), Box::new(val)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -344,6 +344,7 @@ macro_rules! literals {
|
|||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace!("maybe_literal not found, copying {:?}", s);
|
||||||
Cow::Owned(s.to_owned())
|
Cow::Owned(s.to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,7 +398,7 @@ impl Headers {
|
|||||||
pub fn set<H: Header>(&mut self, value: H) {
|
pub fn set<H: Header>(&mut self, value: H) {
|
||||||
trace!("Headers.set( {:?}, {:?} )", header_name::<H>(), HeaderValueString(&value));
|
trace!("Headers.set( {:?}, {:?} )", header_name::<H>(), HeaderValueString(&value));
|
||||||
self.data.insert(HeaderName(Ascii::new(Cow::Borrowed(header_name::<H>()))),
|
self.data.insert(HeaderName(Ascii::new(Cow::Borrowed(header_name::<H>()))),
|
||||||
Item::new_typed(Box::new(value)));
|
Item::new_typed(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a reference to the header field's value, if it exists.
|
/// Get a reference to the header field's value, if it exists.
|
||||||
@@ -682,10 +683,11 @@ impl AsRef<str> for HeaderName {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for HeaderName {
|
impl PartialEq for HeaderName {
|
||||||
|
#[inline]
|
||||||
fn eq(&self, other: &HeaderName) -> bool {
|
fn eq(&self, other: &HeaderName) -> bool {
|
||||||
let s = self.as_ref();
|
let s = self.as_ref();
|
||||||
let k = other.as_ref();
|
let k = other.as_ref();
|
||||||
if s.len() == k.len() && s.as_ptr() == k.as_ptr() {
|
if s.as_ptr() == k.as_ptr() && s.len() == k.len() {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
self.0 == other.0
|
self.0 == other.0
|
||||||
@@ -696,7 +698,7 @@ impl PartialEq for HeaderName {
|
|||||||
impl PartialEq<HeaderName> for str {
|
impl PartialEq<HeaderName> for str {
|
||||||
fn eq(&self, other: &HeaderName) -> bool {
|
fn eq(&self, other: &HeaderName) -> bool {
|
||||||
let k = other.as_ref();
|
let k = other.as_ref();
|
||||||
if self.len() == k.len() && self.as_ptr() == k.as_ptr() {
|
if self.as_ptr() == k.as_ptr() && self.len() == k.len() {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
other.0 == self
|
other.0 == self
|
||||||
@@ -975,6 +977,16 @@ mod tests {
|
|||||||
b.iter(|| assert!(headers.get::<ContentLength>().is_none()))
|
b.iter(|| assert!(headers.get::<ContentLength>().is_none()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
|
#[bench]
|
||||||
|
fn bench_headers_get_miss_previous_10(b: &mut Bencher) {
|
||||||
|
let mut headers = Headers::new();
|
||||||
|
for i in 0..10 {
|
||||||
|
headers.set_raw(format!("non-standard-{}", i), "hi");
|
||||||
|
}
|
||||||
|
b.iter(|| assert!(headers.get::<ContentLength>().is_none()))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_headers_set(b: &mut Bencher) {
|
fn bench_headers_set(b: &mut Bencher) {
|
||||||
@@ -982,6 +994,33 @@ mod tests {
|
|||||||
b.iter(|| headers.set(ContentLength(12)))
|
b.iter(|| headers.set(ContentLength(12)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
|
#[bench]
|
||||||
|
fn bench_headers_set_previous_10(b: &mut Bencher) {
|
||||||
|
let mut headers = Headers::new();
|
||||||
|
for i in 0..10 {
|
||||||
|
headers.set_raw(format!("non-standard-{}", i), "hi");
|
||||||
|
}
|
||||||
|
b.iter(|| headers.set(ContentLength(12)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
|
#[bench]
|
||||||
|
fn bench_headers_set_raw(b: &mut Bencher) {
|
||||||
|
let mut headers = Headers::new();
|
||||||
|
b.iter(|| headers.set_raw("non-standard", "hello"))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
|
#[bench]
|
||||||
|
fn bench_headers_set_raw_previous_10(b: &mut Bencher) {
|
||||||
|
let mut headers = Headers::new();
|
||||||
|
for i in 0..10 {
|
||||||
|
headers.set_raw(format!("non-standard-{}", i), "hi");
|
||||||
|
}
|
||||||
|
b.iter(|| headers.set_raw("non-standard", "hello"))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_headers_has(b: &mut Bencher) {
|
fn bench_headers_has(b: &mut Bencher) {
|
||||||
@@ -1003,8 +1042,16 @@ mod tests {
|
|||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_headers_fmt(b: &mut Bencher) {
|
fn bench_headers_fmt(b: &mut Bencher) {
|
||||||
|
use std::fmt::Write;
|
||||||
|
let mut buf = String::with_capacity(64);
|
||||||
let mut headers = Headers::new();
|
let mut headers = Headers::new();
|
||||||
headers.set(ContentLength(11));
|
headers.set(ContentLength(11));
|
||||||
b.iter(|| headers.to_string())
|
headers.set(ContentType::json());
|
||||||
|
b.bytes = headers.to_string().len() as u64;
|
||||||
|
b.iter(|| {
|
||||||
|
let _ = write!(buf, "{}", headers);
|
||||||
|
::test::black_box(&buf);
|
||||||
|
unsafe { buf.as_mut_vec().set_len(0); }
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user