Skip to content
This repository was archived by the owner on Nov 6, 2024. It is now read-only.

Commit a9ab073

Browse files
roypatJonathanWoollett-Light
authored andcommitted
Avoid temporary Vec<u8> allocation during deserialization
Instead of reusing `Vec::<u8>::deserialize` to defer the deserialization, implement a Visitor that can construct `$typ` directly from the deserialization byte stream. This eliminates a temporary allocation where the input byte stream is first copied into a `Vec<u8>` and later copied to the stack to construct `$typ` via `transmute!`. This saves a few microseconds (up to 1ms on specific hardware) when deserializing microVM snapshots. Signed-off-by: Patrick Roy <roypat@amazon.co.uk>
1 parent 210be87 commit a9ab073

File tree

2 files changed

+16
-5
lines changed

2 files changed

+16
-5
lines changed

coverage_config_x86_64.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"coverage_score": 80.77,
2+
"coverage_score": 78.57,
33
"exclude_path": ".*bindings\\.rs",
44
"crate_features": "fam-wrappers,serde"
55
}

src/serialize.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,24 @@ macro_rules! serde_impls {
2727
where
2828
D: Deserializer<'de>
2929
{
30-
let bytes = Vec::<u8>::deserialize(deserializer)?;
30+
struct BytesVisitor;
3131

32-
let mut backing = [0u8; std::mem::size_of::<$typ>()];
32+
impl<'a> serde::de::Visitor<'a> for BytesVisitor {
33+
type Value = [u8; std::mem::size_of::<$typ>()];
3334

34-
let limit = bytes.len().min(backing.len());
35+
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
36+
formatter.write_str("a byte array")
37+
}
3538

36-
backing[..limit].copy_from_slice(&bytes[..limit]);
39+
fn visit_bytes<E>(self, bytes: &[u8]) -> Result<Self::Value, E> {
40+
let mut backing = [0u8; std::mem::size_of::<$typ>()];
41+
let limit = bytes.len().min(backing.len());
42+
backing[..limit].copy_from_slice(&bytes[..limit]);
43+
Ok(backing)
44+
}
45+
}
46+
47+
let backing = deserializer.deserialize_bytes(BytesVisitor)?;
3748

3849
Ok(transmute!(backing))
3950
}

0 commit comments

Comments
 (0)