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)
```
This commit is contained in:
Matthias Einwag
2021-05-13 22:20:48 -07:00
committed by Dirkjan Ochtman
parent ce66efc045
commit fc950da8aa
3 changed files with 17 additions and 4 deletions
+1 -1
View File
@@ -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::<u32>()?;
+15 -2
View File
@@ -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<Self> {
let len = buf.get::<u8>().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,
}
}
+1 -1
View File
@@ -431,7 +431,7 @@ fn decode_cid(len: usize, value: &mut Option<ConnectionId>, 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(())
}