use std::time::Duration; use criterion::BenchmarkId; use criterion::Criterion; use criterion::Throughput; fn tests() -> Vec<(usize, &'static [u8], Vec)> { use base64::prelude::*; include_bytes!("../src/test_vectors.txt") .split(|&b| b == b'\n') .enumerate() .take(256) .map(|(i, b64)| (i, b64, BASE64_STANDARD.decode(b64).unwrap())) .collect() } fn decoded_len(input: usize) -> usize { input / 4 * 3 + match input % 4 { 1 | 2 => 1, 3 => 2, _ => 0, } } fn decode(c: &mut Criterion) { let mut group = c.benchmark_group("decode"); for (i, enc, _) in tests() { let len = decoded_len( std::str::from_utf8(enc) .unwrap() .trim_end_matches('=') .len(), ); group .warm_up_time(Duration::from_millis(250)) .measurement_time(Duration::from_millis(500)) .sample_size(250) .throughput(Throughput::Bytes(len as u64)) .bench_with_input(BenchmarkId::new("vb64", i), enc, |b, enc| { b.iter(|| vb64::decode(enc)) }) .bench_with_input(BenchmarkId::new("baseline", i), enc, |b, enc| { use base64::prelude::*; b.iter(|| BASE64_STANDARD.decode(enc)) }); } } fn encode(c: &mut Criterion) { let mut group = c.benchmark_group("encode"); for (i, _, dec) in tests() { group .warm_up_time(Duration::from_millis(250)) .measurement_time(Duration::from_millis(500)) .sample_size(250) .throughput(Throughput::Bytes(dec.len() as u64)) .bench_with_input(BenchmarkId::new("vb64", i), &dec, |b, dec| { b.iter(|| vb64::encode(dec)) }) .bench_with_input(BenchmarkId::new("baseline", i), &dec, |b, dec| { use base64::prelude::*; b.iter(|| BASE64_STANDARD.encode(dec)) }); } group.finish(); } criterion::criterion_group!(benches, decode, encode); criterion::criterion_main!(benches);