diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 8204636cec..892040c3a3 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -99,3 +99,7 @@ harness = false name = "trie_root" required-features = ["arbitrary", "test-utils"] harness = false + +[[bench]] +name = "nibbles" +harness = false diff --git a/crates/primitives/benches/nibbles.rs b/crates/primitives/benches/nibbles.rs new file mode 100644 index 0000000000..abe9801a34 --- /dev/null +++ b/crates/primitives/benches/nibbles.rs @@ -0,0 +1,19 @@ +use criterion::{criterion_group, criterion_main, Criterion}; +use reth_primitives::trie::Nibbles; + +/// Benchmarks the nibble unpacking. +pub fn nibbles_benchmark(c: &mut Criterion) { + c.bench_function("Nibbles unpack", |b| { + let raw = (1..=32).collect::>(); + b.iter(|| { + Nibbles::unpack(&raw); + }) + }); +} + +criterion_group! { + name = benches; + config = Criterion::default(); + targets = nibbles_benchmark +} +criterion_main!(benches); diff --git a/crates/primitives/src/trie/nibbles.rs b/crates/primitives/src/trie/nibbles.rs index 876b9ff9a6..d3d862966d 100644 --- a/crates/primitives/src/trie/nibbles.rs +++ b/crates/primitives/src/trie/nibbles.rs @@ -94,14 +94,12 @@ impl Nibbles { /// Take a byte array (slice or vector) as input and convert it into a [Nibbles] struct /// containing the nibbles (half-bytes or 4 bits) that make up the input byte data. pub fn unpack>(data: T) -> Self { - Nibbles { - hex_data: Bytes::from( - data.as_ref() - .iter() - .flat_map(|item| vec![item / 16, item % 16]) - .collect::>(), - ), + let mut vec = Vec::with_capacity(data.as_ref().len() * 2); + for byte in data.as_ref() { + vec.push(byte / 16); + vec.push(byte % 16); } + Nibbles { hex_data: Bytes::from(vec) } } /// Packs the nibbles stored in the struct into a byte vector.