From 923421fd2ddef5ecabfe812d15adda2590cc0b79 Mon Sep 17 00:00:00 2001 From: Conrad Ludgate Date: Mon, 17 Oct 2022 11:38:28 +0100 Subject: [PATCH] avoid int formatting as much as possible (net -70%/-68% on 2822/3339 respectively) --- src/format/mod.rs | 39 +++++++++++++++++++++++++++------------ src/naive/date.rs | 12 ++++++++++-- src/naive/time/mod.rs | 8 +++++++- 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/format/mod.rs b/src/format/mod.rs index ab020c5cf8..ed63e4eb7a 100644 --- a/src/format/mod.rs +++ b/src/format/mod.rs @@ -40,7 +40,6 @@ use alloc::string::{String, ToString}; #[cfg(any(feature = "alloc", feature = "std", test))] use core::borrow::Borrow; use core::fmt; -#[cfg(any(feature = "alloc", feature = "std", test))] use core::fmt::Write; use core::str::FromStr; #[cfg(any(feature = "std", test))] @@ -798,21 +797,37 @@ fn write_rfc2822_inner( return Err(fmt::Error); } + result.push_str(locale.short_weekdays[d.weekday().num_days_from_sunday() as usize]); + result.push_str(", "); + write_hundreds(result, d.day() as u8)?; + result.push(' '); + result.push_str(locale.short_months[d.month0() as usize]); + result.push(' '); + write_hundreds(result, (year / 100) as u8)?; + write_hundreds(result, (year % 100) as u8)?; + result.push(' '); + write_hundreds(result, t.hour() as u8)?; + result.push(':'); + write_hundreds(result, t.minute() as u8)?; + result.push(':'); let sec = t.second() + t.nanosecond() / 1_000_000_000; - write!( - result, - "{}, {:02} {} {:04} {:02}:{:02}:{:02} ", - locale.short_weekdays[d.weekday().num_days_from_sunday() as usize], - d.day(), - locale.short_months[d.month0() as usize], - year, - t.hour(), - t.minute(), - sec - )?; + write_hundreds(result, sec as u8)?; + result.push(' '); write_local_minus_utc(result, off, false, Colons::None) } +/// Equivalent to `{:02}` formatting for n < 100. +pub(crate) fn write_hundreds(w: &mut impl Write, n: u8) -> fmt::Result { + if n >= 100 { + return Err(fmt::Error); + } + + let tens = b'0' + n / 10; + let ones = b'0' + n % 10; + w.write_char(tens as char)?; + w.write_char(ones as char) +} + /// Tries to format given arguments with given formatting items. /// Internally used by `DelayedFormat`. #[cfg(any(feature = "alloc", feature = "std", test))] diff --git a/src/naive/date.rs b/src/naive/date.rs index c5fb7b1725..4e282bd1f9 100644 --- a/src/naive/date.rs +++ b/src/naive/date.rs @@ -1830,14 +1830,22 @@ impl DoubleEndedIterator for NaiveDateWeeksIterator { /// ``` impl fmt::Debug for NaiveDate { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use core::fmt::Write; + let year = self.year(); let mdf = self.mdf(); if (0..=9999).contains(&year) { - write!(f, "{:04}-{:02}-{:02}", year, mdf.month(), mdf.day()) + crate::format::write_hundreds(f, (year / 100) as u8)?; + crate::format::write_hundreds(f, (year % 100) as u8)?; } else { // ISO 8601 requires the explicit sign for out-of-range years - write!(f, "{:+05}-{:02}-{:02}", year, mdf.month(), mdf.day()) + write!(f, "{:+05}", year)?; } + + f.write_char('-')?; + crate::format::write_hundreds(f, mdf.month() as u8)?; + f.write_char('-')?; + crate::format::write_hundreds(f, mdf.day() as u8) } } diff --git a/src/naive/time/mod.rs b/src/naive/time/mod.rs index c79fe6b3c6..4e273373d6 100644 --- a/src/naive/time/mod.rs +++ b/src/naive/time/mod.rs @@ -1188,7 +1188,13 @@ impl fmt::Debug for NaiveTime { (sec, self.frac) }; - write!(f, "{:02}:{:02}:{:02}", hour, min, sec)?; + use core::fmt::Write; + crate::format::write_hundreds(f, hour as u8)?; + f.write_char(':')?; + crate::format::write_hundreds(f, min as u8)?; + f.write_char(':')?; + crate::format::write_hundreds(f, sec as u8)?; + if nano == 0 { Ok(()) } else if nano % 1_000_000 == 0 {