aquatic_http: send_response: use itoa and Vec::with_capacity

This leads to fewer allocations and possibly better performance.
This commit is contained in:
Joakim Frostegård 2020-07-18 03:03:39 +02:00
parent 8ddccb20aa
commit f94c52da77
3 changed files with 44 additions and 4 deletions

1
Cargo.lock generated
View file

@ -81,6 +81,7 @@ dependencies = [
"hashbrown",
"httparse",
"indexmap",
"itoa",
"log",
"mimalloc",
"mio",

View file

@ -24,6 +24,7 @@ flume = "0.7"
hashbrown = { version = "0.7", features = ["serde"] }
httparse = "1"
indexmap = "1"
itoa = "0.4"
log = "0.4"
mimalloc = { version = "0.1", default-features = false }
mio = { version = "0.7", features = ["tcp", "os-poll", "os-util"] }

View file

@ -100,17 +100,22 @@ impl EstablishedConnection {
}
pub fn send_response(&mut self, body: &[u8]) -> ::std::io::Result<()> {
let mut response = Vec::new();
let content_len = body.len() + 2; // 2 is for newlines at end
let content_len_num_digits = Self::num_digits_in_usize(content_len);
let mut response = Vec::with_capacity(
39 + content_len_num_digits + body.len()
);
response.extend_from_slice(b"HTTP/1.1 200 OK\r\nContent-Length: ");
response.extend_from_slice(format!("{}", body.len() + 2).as_bytes());
::itoa::write(&mut response, content_len)?;
response.extend_from_slice(b"\r\n\r\n");
response.extend_from_slice(body);
response.extend_from_slice(b"\r\n");
let bytes_written = self.stream.write(&response)?;
if bytes_written != response.len(){
if bytes_written != response.len() {
::log::error!(
"send_response: only {} out of {} bytes written",
bytes_written,
@ -123,6 +128,18 @@ impl EstablishedConnection {
Ok(())
}
fn num_digits_in_usize(mut number: usize) -> usize {
let mut num_digits = 1usize;
while number >= 10 {
num_digits += 1;
number /= 10;
}
num_digits
}
#[inline]
pub fn clear_buffer(&mut self){
self.bytes_read = 0;
@ -284,4 +301,25 @@ impl Connection {
}
pub type ConnectionMap = HashMap<Token, Connection>;
pub type ConnectionMap = HashMap<Token, Connection>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_num_digits_in_usize(){
let f = EstablishedConnection::num_digits_in_usize;
assert_eq!(f(0), 1);
assert_eq!(f(1), 1);
assert_eq!(f(9), 1);
assert_eq!(f(10), 2);
assert_eq!(f(11), 2);
assert_eq!(f(99), 2);
assert_eq!(f(100), 3);
assert_eq!(f(101), 3);
assert_eq!(f(1000), 4);
}
}