use clock_hash::{
ClockHasher, DomainTag, clockhash256, clockhash256_domain, clockhash256_with_domain, tags,
};
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use std::hint::black_box;
fn bench_oneshot_hashing(c: &mut Criterion) {
let mut group = c.benchmark_group("oneshot_hashing");
let sizes = [0, 1, 16, 64, 256, 1024, 4096, 16384, 65536, 262144, 1048576];
for &size in &sizes {
let data = vec![0x42u8; size];
group.bench_with_input(BenchmarkId::from_parameter(size), &data, |b, data| {
b.iter(|| {
let hash = clockhash256(black_box(data));
black_box(hash);
});
});
}
group.finish();
}
fn bench_incremental_hashing(c: &mut Criterion) {
let mut group = c.benchmark_group("incremental_hashing");
let sizes = [1024, 4096, 16384, 65536, 262144];
for &size in &sizes {
let data = vec![0x42u8; size];
group.bench_with_input(BenchmarkId::from_parameter(size), &data, |b, data| {
b.iter(|| {
let mut hasher = ClockHasher::new();
hasher.update(black_box(data));
let hash = hasher.finalize();
black_box(hash);
});
});
}
group.finish();
}
fn bench_chunked_hashing(c: &mut Criterion) {
let mut group = c.benchmark_group("chunked_hashing");
let total_size = 65536; let chunk_sizes = [1024, 4096, 8192];
for &chunk_size in &chunk_sizes {
let data = vec![0x42u8; total_size];
let chunks: Vec<&[u8]> = data.chunks(chunk_size).collect();
group.bench_with_input(
BenchmarkId::from_parameter(format!("{}_chunks", chunk_size)),
&chunks,
|b, chunks| {
b.iter(|| {
let mut hasher = ClockHasher::new();
for chunk in chunks.iter() {
hasher.update(black_box(chunk));
}
let hash = hasher.finalize();
black_box(hash);
});
},
);
}
group.finish();
}
fn bench_domain_separation(c: &mut Criterion) {
let mut group = c.benchmark_group("domain_separation");
let data = vec![0x42u8; 4096]; let domains = [
("CLK_BLOCK", tags::CLK_BLOCK),
("CLK_TX", tags::CLK_TX),
("CLK_MERKLE", tags::CLK_MERKLE),
("CLK_NONCE", tags::CLK_NONCE),
("CLK_RNG", tags::CLK_RNG),
];
for (name, domain) in &domains {
group.bench_with_input(
BenchmarkId::from_parameter(*name),
&(domain, &data),
|b, (domain, data)| {
b.iter(|| {
let hash = clockhash256_domain(black_box(domain), black_box(data));
black_box(hash);
});
},
);
}
group.finish();
}
fn bench_typed_domain_separation(c: &mut Criterion) {
let mut group = c.benchmark_group("typed_domain_separation");
let data = vec![0x42u8; 4096];
let domains = [
("Block", DomainTag::Block),
("Transaction", DomainTag::Transaction),
("Merkle", DomainTag::Merkle),
("Nonce", DomainTag::Nonce),
("Rng", DomainTag::Rng),
];
for (name, domain) in &domains {
group.bench_with_input(
BenchmarkId::from_parameter(*name),
&(*domain, &data),
|b, (domain, data)| {
b.iter(|| {
let hash = clockhash256_with_domain(black_box(*domain), black_box(data));
black_box(hash);
});
},
);
}
group.finish();
}
fn bench_domain_vs_regular(c: &mut Criterion) {
let mut group = c.benchmark_group("domain_vs_regular");
let data = vec![0x42u8; 8192];
group.bench_function("regular_hash", |b| {
b.iter(|| {
let hash = clockhash256(black_box(&data));
black_box(hash);
});
});
group.bench_function("domain_hash", |b| {
b.iter(|| {
let hash = clockhash256_domain(black_box(tags::CLK_BLOCK), black_box(&data));
black_box(hash);
});
});
group.finish();
}
fn bench_empty_input(c: &mut Criterion) {
let mut group = c.benchmark_group("empty_input");
group.bench_function("empty_oneshot", |b| {
b.iter(|| {
let hash = clockhash256(black_box(&[]));
black_box(hash);
});
});
group.bench_function("empty_incremental", |b| {
b.iter(|| {
let hasher = ClockHasher::new();
let hash = hasher.finalize();
black_box(hash);
});
});
group.finish();
}
fn bench_throughput(c: &mut Criterion) {
let mut group = c.benchmark_group("throughput");
group.throughput(criterion::Throughput::Elements(1048576));
let data = vec![0x42u8; 1048576];
group.bench_function("1MB_oneshot", |b| {
b.iter(|| {
let hash = clockhash256(black_box(&data));
black_box(hash);
});
});
group.finish();
}
fn bench_construction(c: &mut Criterion) {
let mut group = c.benchmark_group("construction");
group.bench_function("new_hasher", |b| {
b.iter(|| {
let hasher = ClockHasher::new();
black_box(hasher);
});
});
group.finish();
}
fn bench_simd_accelerated_hashing(c: &mut Criterion) {
let mut group = c.benchmark_group("simd_accelerated_hashing");
let sizes = [1024, 4096, 16384, 65536];
for &size in &sizes {
let data = vec![0x42u8; size];
group.bench_with_input(
BenchmarkId::from_parameter(format!("{}_bytes_simd", size)),
&data,
|b, data| {
b.iter(|| {
let hash = clockhash256(black_box(data));
black_box(hash);
});
},
);
}
group.finish();
}
fn bench_simd_incremental_hashing(c: &mut Criterion) {
let mut group = c.benchmark_group("simd_incremental_hashing");
let sizes = [4096, 16384, 65536];
for &size in &sizes {
let data = vec![0x42u8; size];
let chunks: Vec<&[u8]> = data.chunks(1024).collect();
group.bench_with_input(
BenchmarkId::from_parameter(format!("{}_bytes_chunked_simd", size)),
&chunks,
|b, chunks| {
b.iter(|| {
let mut hasher = ClockHasher::new();
for chunk in chunks.iter() {
hasher.update(black_box(chunk));
}
let hash = hasher.finalize();
black_box(hash);
});
},
);
}
group.finish();
}
criterion_group!(
benches,
bench_oneshot_hashing,
bench_incremental_hashing,
bench_chunked_hashing,
bench_domain_separation,
bench_typed_domain_separation,
bench_domain_vs_regular,
bench_empty_input,
bench_throughput,
bench_construction,
bench_simd_accelerated_hashing,
bench_simd_incremental_hashing,
);
criterion_main!(benches);