Skip to content

Commit

Permalink
Optimize hexadecimal conversions in serde_utils to speed up JSON seri…
Browse files Browse the repository at this point in the history
…alization of byte collections

Slow serialization to JSON was claimed to be the problem that led to 2e92e00.
BlobSidecar serialization is now around 15.4 times faster.
BlobSidecar deserialization is now around 12 times faster.
SignedBeaconBlock serialization is now up to 1.5 times faster.
SignedBeaconBlock deserialization is now up to 1.1 times faster.

faster-hex might be faster than const-hex in some cases, but faster-hex does not provide the API we require.
See https://crates.io/crates/const-hex/1.14.0 for benchmark results comparing various hexadecimal conversion crates.
  • Loading branch information
weekday-grandine-io authored and povi committed Feb 5, 2025
1 parent 82c1cb5 commit bdb716d
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 8 deletions.
46 changes: 45 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ bytesize = { version = '1', features = ['serde'] }
cached = '0.53'
chrono = '0.4'
clap = { version = '4', features = ['derive'] }
const-hex = '1.14'
const_format = '0.2'
constant_time_eq = '0.3'
conv = '0.3'
Expand Down Expand Up @@ -339,7 +340,6 @@ hash_hasher = '2'
hashlink = '0.9'
hex = { version = '0.4', features = ['serde'] }
hex-literal = '0.4'
hex_fmt = '0.3'
hmac = '0.12'
http = '1'
http-body-util = '0.1'
Expand Down
2 changes: 1 addition & 1 deletion serde_utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ authors = ["Grandine <[email protected]>"]
workspace = true

[dependencies]
const-hex = { workspace = true }
generic-array = { workspace = true }
hex = { workspace = true }
hex_fmt = { workspace = true }
itertools = { workspace = true }
num-traits = { workspace = true }
serde = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion serde_utils/src/prefixed_hex_or_bytes_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub fn deserialize<'de, D: Deserializer<'de>, const N: usize>(
let digits = shared::strip_hex_prefix(string)?;

let mut bytes = [0; N];
hex::decode_to_slice(digits, &mut bytes).map_err(E::custom)?;
const_hex::decode_to_slice(digits, &mut bytes).map_err(E::custom)?;

Ok(bytes)
}
Expand Down
2 changes: 1 addition & 1 deletion serde_utils/src/prefixed_hex_or_bytes_cow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Cow<'de

fn visit_str<E: Error>(self, string: &str) -> Result<Self::Value, E> {
let digits = shared::strip_hex_prefix(string)?;
let bytes = hex::decode(digits).map_err(E::custom)?;
let bytes = const_hex::decode(digits).map_err(E::custom)?;
Ok(Cow::Owned(bytes))
}
}
Expand Down
2 changes: 1 addition & 1 deletion serde_utils/src/prefixed_hex_or_bytes_generic_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub fn deserialize<'de, D: Deserializer<'de>, N: ArrayLength<u8>>(
let digits = shared::strip_hex_prefix(string)?;

let mut bytes = GenericArray::default();
hex::decode_to_slice(digits, &mut bytes).map_err(E::custom)?;
const_hex::decode_to_slice(digits, &mut bytes).map_err(E::custom)?;

Ok(bytes)
}
Expand Down
3 changes: 1 addition & 2 deletions serde_utils/src/prefixed_hex_or_bytes_slice.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use hex_fmt::HexFmt;
use serde::Serializer;

pub fn serialize<S: Serializer>(bytes: impl AsRef<[u8]>, serializer: S) -> Result<S::Ok, S::Error> {
if serializer.is_human_readable() {
serializer.collect_str(&format_args!("0x{}", HexFmt(bytes)))
serializer.serialize_str(const_hex::encode_prefixed(bytes).as_str())
} else {
serializer.serialize_bytes(bytes.as_ref())
}
Expand Down

0 comments on commit bdb716d

Please sign in to comment.