Skip to content

Commit 8c942b4

Browse files
perf(tip5): Avoid one permutation in hash_varlen (#252)
The last step of `hash_varlen` is to read out the hash from the state. Previous this reading-out was followed by a permutation. But since the of the sponge is dropped after the termination of this function, the last permutation is not needed. For short inputs to `hash_varlen` this gives a significant speedup. Short instances of `hash_varlen` is used downstream by `neptune-core` in the pow-guessing process, where this change reduces the number of permutations from nine to seven. Added benchmark shows a 28 % speedup when running `hash_varlen` on an input of length 10. For longer input lengths, this speedup will approach zero. Shoutout to @macro-ss for identifying this speedup. Benchmark results, with this change: ```bash $ cargo criterion --bench tip5 Compiling twenty-first v0.48.0 (/home/thv/repos/twenty-first/twenty-first) Finished `bench` profile [optimized] target(s) in 4.40s Gnuplot not found, using plotters backend tip5/hash_10/Tip5 / Hash 10/10 time: [532.41 ns 532.71 ns 533.02 ns] change: [-0.2022% +0.0630% +0.2673%] (p = 0.66 > 0.05) No change in performance detected. tip5/hash_pair/Tip5 / Hash Pair/pair time: [531.36 ns 533.53 ns 536.38 ns] change: [-1.4081% -1.0392% -0.6529%] (p = 0.00 < 0.05) Change within noise threshold. tip5/hash_varlen/Tip5 / Hash Variable Length/16384 time: [1.0669 ms 1.0682 ms 1.0699 ms] change: [+2.3852% +2.6962% +2.9802%] (p = 0.00 < 0.05) Performance has regressed. tip5/hash_varlen/Tip5 / Hash Variable Length/10 time: [1.3163 µs 1.3181 µs 1.3198 µs] change: [-28.468% -28.273% -28.108%] (p = 0.00 < 0.05) Performance has improved. tip5/parallel/Tip5 / Parallel Hash/65536 time: [1.0509 ms 1.0606 ms 1.0724 ms] change: [-7.4722% -1.6295% +4.5693%] (p = 0.62 > 0.05) No change in performance detected. ``` Co-authored-by: marco-storswift <[email protected]>
1 parent ff0ec3a commit 8c942b4

File tree

2 files changed

+17
-7
lines changed

2 files changed

+17
-7
lines changed

twenty-first/benches/tip5.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,23 @@ fn bench_pair(c: &mut Criterion) {
3333
fn bench_varlen(c: &mut Criterion) {
3434
let mut group = c.benchmark_group("tip5/hash_varlen");
3535

36-
let size = 16_384;
36+
let many = 16_384;
37+
let many_elements: Vec<BFieldElement> = random_elements(many);
38+
3739
group.sample_size(50);
38-
let elements: Vec<BFieldElement> = random_elements(size);
40+
group.bench_function(
41+
BenchmarkId::new("Tip5 / Hash Variable Length", many),
42+
|bencher| {
43+
bencher.iter(|| Tip5::hash_varlen(&many_elements));
44+
},
45+
);
3946

47+
let few = 10;
48+
let few_elements: Vec<BFieldElement> = random_elements(few);
4049
group.bench_function(
41-
BenchmarkId::new("Tip5 / Hash Variable Length", size),
50+
BenchmarkId::new("Tip5 / Hash Variable Length", few),
4251
|bencher| {
43-
bencher.iter(|| Tip5::hash_varlen(&elements));
52+
bencher.iter(|| Tip5::hash_varlen(&few_elements));
4453
},
4554
);
4655
}

twenty-first/src/math/tip5.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -627,13 +627,14 @@ impl Tip5 {
627627
//
628628
// - Apply the correct padding
629629
// - [Sponge::pad_and_absorb_all()]
630-
// - [Sponge::squeeze()] once.
630+
// - Read the digest from the resulting state.
631631
pub fn hash_varlen(input: &[BFieldElement]) -> Digest {
632632
let mut sponge = Self::init();
633633
sponge.pad_and_absorb_all(input);
634-
let produce: [BFieldElement; crate::util_types::sponge::RATE] = sponge.squeeze();
634+
let produce: [BFieldElement; Digest::LEN] =
635+
(&sponge.state[..Digest::LEN]).try_into().unwrap();
635636

636-
Digest::new((&produce[..Digest::LEN]).try_into().unwrap())
637+
Digest::new(produce)
637638
}
638639

639640
/// Produce `num_indices` random integer values in the range `[0, upper_bound)`. The

0 commit comments

Comments
 (0)