use criterion::{criterion_group, criterion_main}; use criterion::{BenchmarkId, Criterion}; #[cfg(unix)] use pprof::criterion::{Output, PProfProfiler}; use ppp::v2; fn ipv6_input() -> Vec { let prefix = b"\r\n\r\n\0\r\nQUIT\n"; let mut input: Vec = Vec::with_capacity(prefix.len()); input.extend_from_slice(prefix); input.push(0x21); input.push(0x21); input.extend(&[0, 45]); input.extend(&[ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ]); input.extend(&[ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, ]); input.extend(&[0, 80]); input.extend(&[1, 187]); input.extend(&[1, 0, 1, 5]); input.extend(&[2, 0, 2, 5, 5]); input } fn ipv4_input() -> Vec { let prefix = b"\r\n\r\n\0\r\nQUIT\n"; let mut input: Vec = Vec::with_capacity(prefix.len()); input.extend_from_slice(prefix); input.push(0x21); input.push(0x11); input.extend(&[0, 26]); input.extend(&[127, 0, 0, 1]); input.extend(&[198, 168, 1, 1]); input.extend(&[0, 80]); input.extend(&[1, 187]); input.extend(&[1, 0, 1, 5]); input.extend(&[2, 0, 2, 5, 5]); input.extend(&[2, 0, 2, 5, 5]); input } fn benchmarks(c: &mut Criterion) { let mut group = c.benchmark_group("PPP Binary"); let inputs = [ ("IPv4 with TLVs", ipv4_input()), ("IPv6 without TLVs", ipv6_input()), ]; for (id, input) in inputs { group.bench_with_input( BenchmarkId::new("v2::Header::try_from", id), input.as_slice(), |b, i| { b.iter(|| v2::Header::try_from(i).unwrap()); }, ); group.bench_with_input( BenchmarkId::new("v2::Header::as_bytes", id), &v2::Header::try_from(input.as_slice()).unwrap(), |b, h| { b.iter(|| h.as_bytes()); }, ); } let source_address = [ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, ]; let destination_address = [ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, ]; let addresses = v2::Addresses::IPv6(v2::IPv6::new(source_address, destination_address, 80, 443)); group.bench_with_input( BenchmarkId::new("v2::Builder::build", "IPv6 with TLVs"), &addresses, |b, a| { b.iter(|| { v2::Builder::new( v2::Version::Two | v2::Command::Local, v2::AddressFamily::IPv6 | v2::Protocol::Unspecified, ) .write_payload(a) .unwrap() .write_payloads(vec![(v2::Type::NoOp, [0].as_slice())]) .unwrap() .write_tlv(v2::Type::NoOp, [42].as_slice()) .unwrap() .build() .unwrap() }) }, ); group.bench_with_input( BenchmarkId::new("v2::Builder::build", "IPv6 with TLVs with length"), &addresses, |b, &a| { b.iter(|| { v2::Builder::with_addresses( v2::Version::Two | v2::Command::Local, v2::Protocol::Unspecified, a, ) .reserve_capacity(8) .write_payloads([ (v2::Type::NoOp, [0].as_slice()), (v2::Type::NoOp, [42].as_slice()), ]) .unwrap() .build() .unwrap() }) }, ); group.finish(); } #[cfg(unix)] criterion_group! { name = benches; config = { Criterion::default().with_profiler(PProfProfiler::new(100, Output::Protobuf)) }; targets = benchmarks } #[cfg(not(unix))] criterion_group!(benches, benchmarks); criterion_main!(benches);