perf(lib): improve parsing by using uninitialized httparse header array
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
use bytes::{BytesMut, Bytes};
|
use bytes::{BytesMut, Bytes};
|
||||||
use http::header::{CONTENT_LENGTH, DATE, Entry, HeaderName, HeaderValue, TRANSFER_ENCODING};
|
use http::header::{CONTENT_LENGTH, DATE, Entry, HeaderName, HeaderValue, TRANSFER_ENCODING};
|
||||||
@@ -32,12 +33,13 @@ where
|
|||||||
if buf.len() == 0 {
|
if buf.len() == 0 {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
let mut headers_indices = [HeaderIndices {
|
// Unsafe: both headers_indices and headers are using unitialized memory,
|
||||||
name: (0, 0),
|
// but we *never* read any of it until after httparse has assigned
|
||||||
value: (0, 0)
|
// values into it. By not zeroing out the stack memory, this saves
|
||||||
}; MAX_HEADERS];
|
// a good ~5% on pipeline benchmarks.
|
||||||
|
let mut headers_indices: [HeaderIndices; MAX_HEADERS] = unsafe { mem::uninitialized() };
|
||||||
let (len, method, path, version, headers_len) = {
|
let (len, method, path, version, headers_len) = {
|
||||||
let mut headers = [httparse::EMPTY_HEADER; MAX_HEADERS];
|
let mut headers: [httparse::Header; MAX_HEADERS] = unsafe { mem::uninitialized() };
|
||||||
trace!("Request.parse([Header; {}], [u8; {}])", headers.len(), buf.len());
|
trace!("Request.parse([Header; {}], [u8; {}])", headers.len(), buf.len());
|
||||||
let mut req = httparse::Request::new(&mut headers);
|
let mut req = httparse::Request::new(&mut headers);
|
||||||
match req.parse(&buf)? {
|
match req.parse(&buf)? {
|
||||||
@@ -262,12 +264,10 @@ where
|
|||||||
if buf.len() == 0 {
|
if buf.len() == 0 {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
let mut headers_indices = [HeaderIndices {
|
// Unsafe: see comment in Server Http1Transaction, above.
|
||||||
name: (0, 0),
|
let mut headers_indices: [HeaderIndices; MAX_HEADERS] = unsafe { mem::uninitialized() };
|
||||||
value: (0, 0)
|
|
||||||
}; MAX_HEADERS];
|
|
||||||
let (len, status, version, headers_len) = {
|
let (len, status, version, headers_len) = {
|
||||||
let mut headers = [httparse::EMPTY_HEADER; MAX_HEADERS];
|
let mut headers: [httparse::Header; MAX_HEADERS] = unsafe { mem::uninitialized() };
|
||||||
trace!("Response.parse([Header; {}], [u8; {}])", headers.len(), buf.len());
|
trace!("Response.parse([Header; {}], [u8; {}])", headers.len(), buf.len());
|
||||||
let mut res = httparse::Response::new(&mut headers);
|
let mut res = httparse::Response::new(&mut headers);
|
||||||
let bytes = buf.as_ref();
|
let bytes = buf.as_ref();
|
||||||
|
|||||||
Reference in New Issue
Block a user