From 857a805993025734201e228e14537f0397bfb8ea Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Tue, 16 Mar 2021 09:43:52 -0400 Subject: [PATCH] Faster Ipv4 serialization prototype --- serde/src/ser/impls.rs | 44 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 431a478cc..f4ae80bd1 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -674,6 +674,40 @@ impl Serialize for net::IpAddr { } } +#[inline] +fn format_u8(mut v: u8, out: &mut [u8]) -> usize { + assert!(out.len() >= 3); + let mut written = 0; + let hundreds = v / 100; + v -= 100 * hundreds; + let tens = v / 10; + v -= 10 * tens; + let ones = v; + if hundreds > 0 { + out[written] = b'0' + hundreds; + written += 1; + } + if hundreds > 0 || tens > 0 { + out[written] = b'0' + tens; + written += 1; + } + out[written] = b'0' + ones; + written += 1; + written +} + +#[cfg(test)] +mod format_u8_tests { + #[test] + fn all() { + for i in 0..(u8::MAX as u16) { + let mut buf = [0u8; 3]; + let written = super::format_u8(i as u8, &mut buf); + assert_eq!(i.to_string().as_bytes(), &buf[..written]); + } + } +} + #[cfg(feature = "std")] impl Serialize for net::Ipv4Addr { fn serialize(&self, serializer: S) -> Result @@ -683,7 +717,15 @@ impl Serialize for net::Ipv4Addr { if serializer.is_human_readable() { const MAX_LEN: usize = 15; debug_assert_eq!(MAX_LEN, "101.102.103.104".len()); - serialize_display_bounded_length!(self, MAX_LEN, serializer) + let mut buf = [0u8; MAX_LEN]; + let mut written = 0; + written += format_u8(self.octets()[0], &mut buf); + for oct in &self.octets()[1..] { + buf[written] = b'.'; + written += 1; + written += format_u8(*oct, &mut buf[written..]); + } + serializer.serialize_str(str::from_utf8(&buf[..written]).unwrap()) } else { self.octets().serialize(serializer) }