1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2025-01-05 06:48:44 +00:00

Merge pull request #1530 from NickKolpinskiy/itoa

Use `itoa` in the content-length helper
This commit is contained in:
Yuki Okushi 2020-05-22 13:03:50 +09:00 committed by GitHub
commit 2550f00702
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 93 deletions

View file

@ -64,6 +64,7 @@ h2 = "0.2.1"
http = "0.2.0" http = "0.2.0"
httparse = "1.3" httparse = "1.3"
indexmap = "1.3" indexmap = "1.3"
itoa = "0.4"
lazy_static = "1.4" lazy_static = "1.4"
language-tags = "0.2" language-tags = "0.2"
log = "0.4" log = "0.4"

View file

@ -25,6 +25,13 @@ fn bench_write_content_length(c: &mut Criterion) {
_new::write_content_length(i, &mut b) _new::write_content_length(i, &mut b)
}) })
}); });
group.bench_with_input(BenchmarkId::new("itoa", i), i, |b, &i| {
b.iter(|| {
let mut b = BytesMut::with_capacity(35);
_itoa::write_content_length(i, &mut b)
})
});
} }
group.finish(); group.finish();
@ -33,6 +40,23 @@ fn bench_write_content_length(c: &mut Criterion) {
criterion_group!(benches, bench_write_content_length); criterion_group!(benches, bench_write_content_length);
criterion_main!(benches); criterion_main!(benches);
mod _itoa {
use bytes::{BufMut, BytesMut};
pub fn write_content_length(n: usize, bytes: &mut BytesMut) {
if n == 0 {
bytes.put_slice(b"\r\ncontent-length: 0\r\n");
return;
}
let mut buf = itoa::Buffer::new();
bytes.put_slice(b"\r\ncontent-length: ");
bytes.put_slice(buf.format(n).as_bytes());
bytes.put_slice(b"\r\n");
}
}
mod _new { mod _new {
use bytes::{BufMut, BytesMut}; use bytes::{BufMut, BytesMut};

View file

@ -31,103 +31,18 @@ pub(crate) fn write_status_line(version: Version, n: u16, bytes: &mut BytesMut)
/// NOTE: bytes object has to contain enough space /// NOTE: bytes object has to contain enough space
pub fn write_content_length(n: u64, bytes: &mut BytesMut) { pub fn write_content_length(n: u64, bytes: &mut BytesMut) {
if n == 0 {
bytes.put_slice(b"\r\ncontent-length: 0\r\n");
return;
}
let mut buf = itoa::Buffer::new();
bytes.put_slice(b"\r\ncontent-length: "); bytes.put_slice(b"\r\ncontent-length: ");
bytes.put_slice(buf.format(n).as_bytes());
if n < 10 {
bytes.put_u8(DIGITS_START + (n as u8));
} else if n < 100 {
let n = n as u8;
let d10 = n / 10;
let d1 = n % 10;
bytes.put_u8(DIGITS_START + d10);
bytes.put_u8(DIGITS_START + d1);
} else if n < 1000 {
let n = n as u16;
let d100 = (n / 100) as u8;
let d10 = ((n / 10) % 10) as u8;
let d1 = (n % 10) as u8;
bytes.put_u8(DIGITS_START + d100);
bytes.put_u8(DIGITS_START + d10);
bytes.put_u8(DIGITS_START + d1);
} else if n < 10_000 {
let n = n as u16;
let d1000 = (n / 1000) as u8;
let d100 = ((n / 100) % 10) as u8;
let d10 = ((n / 10) % 10) as u8;
let d1 = (n % 10) as u8;
bytes.put_u8(DIGITS_START + d1000);
bytes.put_u8(DIGITS_START + d100);
bytes.put_u8(DIGITS_START + d10);
bytes.put_u8(DIGITS_START + d1);
} else if n < 100_000 {
let n = n as u32;
let d10000 = (n / 10000) as u8;
let d1000 = ((n / 1000) % 10) as u8;
let d100 = ((n / 100) % 10) as u8;
let d10 = ((n / 10) % 10) as u8;
let d1 = (n % 10) as u8;
bytes.put_u8(DIGITS_START + d10000);
bytes.put_u8(DIGITS_START + d1000);
bytes.put_u8(DIGITS_START + d100);
bytes.put_u8(DIGITS_START + d10);
bytes.put_u8(DIGITS_START + d1);
} else if n < 1_000_000 {
let n = n as u32;
let d100000 = (n / 100_000) as u8;
let d10000 = ((n / 10000) % 10) as u8;
let d1000 = ((n / 1000) % 10) as u8;
let d100 = ((n / 100) % 10) as u8;
let d10 = ((n / 10) % 10) as u8;
let d1 = (n % 10) as u8;
bytes.put_u8(DIGITS_START + d100000);
bytes.put_u8(DIGITS_START + d10000);
bytes.put_u8(DIGITS_START + d1000);
bytes.put_u8(DIGITS_START + d100);
bytes.put_u8(DIGITS_START + d10);
bytes.put_u8(DIGITS_START + d1);
} else {
write_u64(n, bytes);
}
bytes.put_slice(b"\r\n"); bytes.put_slice(b"\r\n");
} }
pub(crate) fn write_u64(n: u64, bytes: &mut BytesMut) {
let mut n = n;
// 20 chars is max length of a u64 (2^64)
// digits will be added to the buffer from lsd to msd
let mut buf = BytesMut::with_capacity(20);
while n > 9 {
// "pop" the least-significant digit
let lsd = (n % 10) as u8;
// remove the lsd from n
n /= 10;
buf.put_u8(DIGITS_START + lsd);
}
// put msd to result buffer
bytes.put_u8(DIGITS_START + (n as u8));
// put, in reverse (msd to lsd), remaining digits to buffer
for i in (0..buf.len()).rev() {
bytes.put_u8(buf[i]);
}
}
pub(crate) struct Writer<'a>(pub &'a mut BytesMut); pub(crate) struct Writer<'a>(pub &'a mut BytesMut);
impl<'a> io::Write for Writer<'a> { impl<'a> io::Write for Writer<'a> {