use cachekit_core::{ByteStorage, StorageEnvelope, ZeroKnowledgeEncryptor};
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
const SIZES: &[usize] = &[64, 256, 1024, 4 * 1024, 16 * 1024, 64 * 1024];
fn make_payload(size: usize) -> Vec<u8> {
(0..size).map(|i| (i % 256) as u8).collect()
}
fn incompressible(len: usize) -> Vec<u8> {
let mut state: u64 = 0x9e3779b97f4a7c15;
let mut out = Vec::with_capacity(len + 8);
while out.len() < len {
state ^= state << 13;
state ^= state >> 7;
state ^= state << 17;
out.extend_from_slice(&state.wrapping_mul(0x2545f4914f6cdd1d).to_le_bytes());
}
out.truncate(len);
out
}
fn bench_envelope_codec_64mib(c: &mut Criterion) {
const SIZE: usize = 64 * 1024 * 1024;
let storage = ByteStorage::new(None);
let payload = incompressible(SIZE);
let wire = storage.store(&payload, None).unwrap();
let envelope: StorageEnvelope = rmp_serde::from_slice(&wire).unwrap();
assert!(
envelope.compressed_data.len() >= SIZE,
"bench payload must be incompressible"
);
eprintln!(
"64mib_incompressible: compressed_data {} B, envelope wire {} B (ratio {:.4})",
envelope.compressed_data.len(),
wire.len(),
wire.len() as f64 / envelope.compressed_data.len() as f64
);
let mut group = c.benchmark_group("byte_storage/64mib_incompressible");
group.sample_size(10);
group.throughput(Throughput::Bytes(SIZE as u64));
group.bench_function("envelope_encode", |b| {
b.iter(|| black_box(rmp_serde::to_vec(black_box(&envelope)).unwrap()));
});
group.bench_function("envelope_decode", |b| {
b.iter(|| black_box(rmp_serde::from_slice::<StorageEnvelope>(black_box(&wire)).unwrap()));
});
group.bench_function("store_e2e", |b| {
b.iter(|| black_box(storage.store(black_box(&payload), None).unwrap()));
});
group.bench_function("retrieve_e2e", |b| {
b.iter(|| black_box(storage.retrieve(black_box(&wire)).unwrap()));
});
group.finish();
}
fn bench_byte_storage_roundtrip(c: &mut Criterion) {
let storage = ByteStorage::new(None);
let mut group = c.benchmark_group("byte_storage/roundtrip");
for &size in SIZES {
let data = make_payload(size);
group.throughput(Throughput::Bytes(size as u64));
group.bench_with_input(BenchmarkId::from_parameter(size), &data, |b, data| {
b.iter(|| {
let envelope = storage.store(black_box(data), None).unwrap();
let (out, _fmt) = storage.retrieve(black_box(&envelope)).unwrap();
black_box(out);
});
});
}
group.finish();
}
fn bench_encrypt_decrypt(c: &mut Criterion) {
let encryptor = ZeroKnowledgeEncryptor::new().unwrap();
let key = [0x42u8; 32];
let aad = b"bench-aad";
let mut group = c.benchmark_group("encryption/aes_gcm_roundtrip");
for &size in SIZES {
let plaintext = make_payload(size);
group.throughput(Throughput::Bytes(size as u64));
group.bench_with_input(BenchmarkId::from_parameter(size), &plaintext, |b, pt| {
b.iter(|| {
let ct = encryptor.encrypt_aes_gcm(black_box(pt), &key, aad).unwrap();
let pt2 = encryptor
.decrypt_aes_gcm(black_box(&ct), &key, aad)
.unwrap();
black_box(pt2);
});
});
}
group.finish();
}
criterion_group!(
benches,
bench_byte_storage_roundtrip,
bench_encrypt_decrypt,
bench_envelope_codec_64mib
);
criterion_main!(benches);