From 635ea464f4582963963604175d48d58e06ae6fd4 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Wed, 24 Jan 2024 03:46:03 +0000 Subject: [PATCH] perf: remove unnecessary allocation when writing http dates --- .github/workflows/ci.yml | 2 ++ actix-http/Cargo.toml | 5 +++++ actix-http/benches/date-formatting.rs | 20 ++++++++++++++++++++ actix-http/src/date.rs | 2 +- actix-http/src/header/shared/http_date.rs | 5 ++--- 5 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 actix-http/benches/date-formatting.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9dcd8fab934..7d4d1a4b286 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,6 +57,8 @@ jobs: - name: workaround MSRV issues if: matrix.version.name == 'msrv' run: | + cargo update -p=ciborium --precise=0.2.1 + cargo update -p=ciborium-ll --precise=0.2.1 cargo update -p=clap --precise=4.3.24 cargo update -p=clap_lex --precise=0.5.0 cargo update -p=anstyle --precise=1.0.2 diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index 6c53f35cc9e..aa243b04bd0 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -113,6 +113,7 @@ actix-web = "4" async-stream = "0.3" criterion = { version = "0.5", features = ["html_reports"] } +divan = "0.1.8" env_logger = "0.10" futures-util = { version = "0.3.17", default-features = false, features = ["alloc"] } memchr = "2.4" @@ -140,3 +141,7 @@ required-features = ["http2", "rustls-0_21"] name = "response-body-compression" harness = false required-features = ["compress-brotli", "compress-gzip", "compress-zstd"] + +[[bench]] +name = "date-formatting" +harness = false diff --git a/actix-http/benches/date-formatting.rs b/actix-http/benches/date-formatting.rs new file mode 100644 index 00000000000..26d0f3daac9 --- /dev/null +++ b/actix-http/benches/date-formatting.rs @@ -0,0 +1,20 @@ +use std::time::SystemTime; + +use actix_http::header::HttpDate; +use divan::{black_box, AllocProfiler, Bencher}; + +#[global_allocator] +static ALLOC: AllocProfiler = AllocProfiler::system(); + +#[divan::bench] +fn date_formatting(b: Bencher<'_, '_>) { + let now = SystemTime::now(); + + b.bench(|| { + black_box(HttpDate::from(black_box(now)).to_string()); + }) +} + +fn main() { + divan::main(); +} diff --git a/actix-http/src/date.rs b/actix-http/src/date.rs index 1358bbd8c3f..735dd91004d 100644 --- a/actix-http/src/date.rs +++ b/actix-http/src/date.rs @@ -28,7 +28,7 @@ impl Date { fn update(&mut self) { self.pos = 0; - write!(self, "{}", httpdate::fmt_http_date(SystemTime::now())).unwrap(); + write!(self, "{}", httpdate::HttpDate::from(SystemTime::now())).unwrap(); } } diff --git a/actix-http/src/header/shared/http_date.rs b/actix-http/src/header/shared/http_date.rs index 21ed49f0cc6..bdfbc7051da 100644 --- a/actix-http/src/header/shared/http_date.rs +++ b/actix-http/src/header/shared/http_date.rs @@ -24,8 +24,7 @@ impl FromStr for HttpDate { impl fmt::Display for HttpDate { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let date_str = httpdate::fmt_http_date(self.0); - f.write_str(&date_str) + httpdate::HttpDate::from(self.0).fmt(f) } } @@ -37,7 +36,7 @@ impl TryIntoHeaderValue for HttpDate { let mut wrt = MutWriter(&mut buf); // unwrap: date output is known to be well formed and of known length - write!(wrt, "{}", httpdate::fmt_http_date(self.0)).unwrap(); + write!(wrt, "{}", self).unwrap(); HeaderValue::from_maybe_shared(buf.split().freeze()) }