1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-28 09:42:40 +01:00

optimize http message serialization

This commit is contained in:
Nikolay Kim 2018-02-19 17:21:04 -08:00
parent 4d81186059
commit 6ee14efbe2
4 changed files with 61 additions and 14 deletions

View File

@ -74,6 +74,7 @@ impl SharedMessagePool {
SharedMessagePool(RefCell::new(VecDeque::with_capacity(128)))
}
#[inline]
pub fn get(&self) -> Rc<HttpMessage> {
if let Some(msg) = self.0.borrow_mut().pop_front() {
msg
@ -82,6 +83,7 @@ impl SharedMessagePool {
}
}
#[inline]
pub fn release(&self, mut msg: Rc<HttpMessage>) {
let v = &mut self.0.borrow_mut();
if v.len() < 128 {

View File

@ -21,6 +21,7 @@ struct Inner {
named: HashMap<String, (Pattern, bool)>,
patterns: Vec<Pattern>,
srv: ServerSettings,
hasroutes: bool,
}
impl Router {
@ -55,6 +56,7 @@ impl Router {
regset: RegexSet::new(&paths).unwrap(),
named: named,
patterns: patterns,
hasroutes: !paths.is_empty(),
srv: settings })), resources)
}
@ -72,6 +74,7 @@ impl Router {
/// Query for matched resource
pub fn recognize<S>(&self, req: &mut HttpRequest<S>) -> Option<usize> {
if !self.0.hasroutes { return None }
let mut idx = None;
{
if self.0.prefix_len > req.path().len() {

View File

@ -1,4 +1,4 @@
use std::io;
use std::{io, mem};
use bytes::BufMut;
use futures::{Async, Poll};
use tokio_io::AsyncWrite;
@ -135,38 +135,60 @@ impl<T: AsyncWrite> Writer for H1Writer<T> {
// status line
helpers::write_status_line(version, msg.status().as_u16(), &mut buffer);
buffer.extend_from_slice(msg.reason().as_bytes());
SharedBytes::extend_from_slice_(buffer, msg.reason().as_bytes());
match body {
Body::Empty =>
if req.method != Method::HEAD {
buffer.extend_from_slice(b"\r\ncontent-length: 0\r\n");
SharedBytes::extend_from_slice_(buffer, b"\r\ncontent-length: 0\r\n");
} else {
buffer.extend_from_slice(b"\r\n");
SharedBytes::extend_from_slice_(buffer, b"\r\n");
},
Body::Binary(ref bytes) =>
helpers::write_content_length(bytes.len(), &mut buffer),
_ =>
buffer.extend_from_slice(b"\r\n"),
SharedBytes::extend_from_slice_(buffer, b"\r\n"),
}
// write headers
let mut pos = 0;
let mut remaining = buffer.remaining_mut();
let mut buf: &mut [u8] = unsafe{ mem::transmute(buffer.bytes_mut()) };
for (key, value) in msg.headers() {
let v = value.as_ref();
let k = key.as_str().as_bytes();
buffer.reserve(k.len() + v.len() + 4);
buffer.put_slice(k);
buffer.put_slice(b": ");
buffer.put_slice(v);
buffer.put_slice(b"\r\n");
let len = k.len() + v.len() + 4;
if len > remaining {
unsafe{buffer.advance_mut(pos)};
pos = 0;
buffer.reserve(len);
remaining = buffer.remaining_mut();
buf = unsafe{ mem::transmute(buffer.bytes_mut()) };
}
buf[pos..pos+k.len()].copy_from_slice(k);
pos += k.len();
buf[pos..pos+2].copy_from_slice(b": ");
pos += 2;
buf[pos..pos+v.len()].copy_from_slice(v);
pos += v.len();
buf[pos..pos+2].copy_from_slice(b"\r\n");
pos += 2;
remaining -= len;
//buffer.put_slice(k);
//buffer.put_slice(b": ");
//buffer.put_slice(v);
//buffer.put_slice(b"\r\n");
}
unsafe{buffer.advance_mut(pos)};
// using helpers::date is quite a lot faster
if !msg.headers().contains_key(DATE) {
helpers::date(&mut buffer);
} else {
// msg eof
buffer.extend_from_slice(b"\r\n");
SharedBytes::extend_from_slice_(buffer, b"\r\n");
}
self.headers_size = buffer.len() as u32;
}

View File

@ -2,7 +2,7 @@ use std::mem;
use std::cell::RefCell;
use std::rc::Rc;
use std::collections::VecDeque;
use bytes::BytesMut;
use bytes::{BufMut, BytesMut};
use body::Binary;
@ -98,12 +98,32 @@ impl SharedBytes {
#[inline]
#[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))]
pub fn extend(&self, data: Binary) {
self.get_mut().extend_from_slice(data.as_ref());
let buf = self.get_mut();
let data = data.as_ref();
buf.reserve(data.len());
SharedBytes::put_slice(buf, data);
}
#[inline]
pub fn extend_from_slice(&self, data: &[u8]) {
self.get_mut().extend_from_slice(data);
let buf = self.get_mut();
buf.reserve(data.len());
SharedBytes::put_slice(buf, data);
}
#[inline]
pub(crate) fn put_slice(buf: &mut BytesMut, src: &[u8]) {
let len = src.len();
unsafe {
buf.bytes_mut()[..len].copy_from_slice(src);
buf.advance_mut(len);
}
}
#[inline]
pub(crate) fn extend_from_slice_(buf: &mut BytesMut, data: &[u8]) {
buf.reserve(data.len());
SharedBytes::put_slice(buf, data);
}
}