From fc950da8aa77ca166126b2bed19748198b129d50 Mon Sep 17 00:00:00 2001 From: Matthias Einwag Date: Thu, 13 May 2021 22:20:48 -0700 Subject: [PATCH] Avoid allocations for CIDs When reading CIDs from packets the current code makes some short-lived allocations due to the use of `copy_to_bytes`, which allocate for 1.5% of CPU samples. This change avoids this. **Before:** ``` Sent 1073741824 bytes on 1 streams in 1.72s (594.74 MiB/s) ``` **After:** ``` Sent 1073741824 bytes on 1 streams in 1.70s (602.78 MiB/s) ``` --- quinn-proto/src/packet.rs | 2 +- quinn-proto/src/shared.rs | 17 +++++++++++++++-- quinn-proto/src/transport_parameters.rs | 2 +- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/quinn-proto/src/packet.rs b/quinn-proto/src/packet.rs index 698831bde..c2b5bee18 100644 --- a/quinn-proto/src/packet.rs +++ b/quinn-proto/src/packet.rs @@ -538,7 +538,7 @@ impl PlainHeader { Ok(PlainHeader::Short { first, spin, - dst_cid: ConnectionId::new(&buf.copy_to_bytes(local_cid_len)), + dst_cid: ConnectionId::from_buf(buf, local_cid_len), }) } else { let version = buf.get::()?; diff --git a/quinn-proto/src/shared.rs b/quinn-proto/src/shared.rs index f5634e7f7..bc4602f2c 100644 --- a/quinn-proto/src/shared.rs +++ b/quinn-proto/src/shared.rs @@ -75,7 +75,20 @@ impl ConnectionId { len: bytes.len() as u8, bytes: [0; MAX_CID_SIZE], }; - res.bytes[..bytes.len()].clone_from_slice(&bytes); + res.bytes[..bytes.len()].copy_from_slice(bytes); + res + } + + /// Constructs cid by reading `len` bytes from a `Buf` + /// + /// Callers need to assure that `buf.remaining() >= len` + pub(crate) fn from_buf(buf: &mut impl Buf, len: usize) -> Self { + debug_assert!(len <= MAX_CID_SIZE); + let mut res = Self { + len: len as u8, + bytes: [0; MAX_CID_SIZE], + }; + buf.copy_to_slice(&mut res[..len]); res } @@ -83,7 +96,7 @@ impl ConnectionId { pub(crate) fn decode_long(buf: &mut impl Buf) -> Option { let len = buf.get::().ok()? as usize; match len > MAX_CID_SIZE || buf.remaining() < len { - false => Some(ConnectionId::new(&buf.copy_to_bytes(len))), + false => Some(Self::from_buf(buf, len)), true => None, } } diff --git a/quinn-proto/src/transport_parameters.rs b/quinn-proto/src/transport_parameters.rs index d0e933dc7..4be1e3d27 100644 --- a/quinn-proto/src/transport_parameters.rs +++ b/quinn-proto/src/transport_parameters.rs @@ -431,7 +431,7 @@ fn decode_cid(len: usize, value: &mut Option, r: &mut impl Buf) -> return Err(Error::Malformed); } - *value = Some(ConnectionId::new(&r.copy_to_bytes(len))); + *value = Some(ConnectionId::from_buf(r, len)); Ok(()) }