use criterion::{criterion_group, criterion_main, BatchSize, Criterion, Throughput}; use mutnet::ipv4::{Ipv4Methods, ParseIpv4Error}; include!("utils.rs"); #[inline(always)] pub fn parse_ipv4( bytes: &[u8], ) -> Result>, ParseIpv4Error> { DataBuffer::<_, Ipv4>::parse_ipv4_alone(bytes, 0, false) } #[allow(clippy::type_complexity)] #[inline(always)] fn mutnet_get_functions_inlined( data_buffer: &impl Ipv4Methods, ) -> ( u8, u8, u8, u8, u16, u16, bool, bool, u16, u8, u8, u16, Ipv4Addr, Ipv4Addr, u16, ) { ( data_buffer.ipv4_version(), data_buffer.ipv4_ihl(), data_buffer.ipv4_dscp(), data_buffer.ipv4_ecn(), data_buffer.ipv4_total_length(), data_buffer.ipv4_identification(), data_buffer.ipv4_dont_fragment_flag(), data_buffer.ipv4_more_fragments_flag(), data_buffer.ipv4_fragment_offset(), data_buffer.ipv4_time_to_live(), data_buffer.ipv4_protocol(), data_buffer.ipv4_header_checksum(), data_buffer.ipv4_source(), data_buffer.ipv4_destination(), data_buffer.ipv4_payload_length(), ) } #[allow(clippy::type_complexity)] #[inline(never)] fn mutnet_get_functions_not_inlined( data_buffer: &impl Ipv4Methods, ) -> ( u8, u8, u8, u8, u16, u16, bool, bool, u16, u8, u8, u16, Ipv4Addr, Ipv4Addr, u16, ) { ( data_buffer.ipv4_version(), data_buffer.ipv4_ihl(), data_buffer.ipv4_dscp(), data_buffer.ipv4_ecn(), data_buffer.ipv4_total_length(), data_buffer.ipv4_identification(), data_buffer.ipv4_dont_fragment_flag(), data_buffer.ipv4_more_fragments_flag(), data_buffer.ipv4_fragment_offset(), data_buffer.ipv4_time_to_live(), data_buffer.ipv4_protocol(), data_buffer.ipv4_header_checksum(), data_buffer.ipv4_source(), data_buffer.ipv4_destination(), data_buffer.ipv4_payload_length(), ) } #[inline(always)] fn parse_ipv4_etherparse( bytes: &[u8], ) -> Result { etherparse::Ipv4HeaderSlice::from_slice(bytes) } #[allow(clippy::type_complexity)] #[inline(always)] fn etherparse_get_functions_inlined( data_buffer: ðerparse::Ipv4HeaderSlice, ) -> ( u8, u8, u8, u8, u16, u16, bool, bool, u16, u8, u8, u16, [u8; 4], [u8; 4], u16, ) { ( data_buffer.version(), data_buffer.ihl(), data_buffer.dcp().value(), data_buffer.ecn().value(), data_buffer.total_len(), data_buffer.identification(), data_buffer.dont_fragment(), data_buffer.more_fragments(), data_buffer.fragments_offset().value(), data_buffer.ttl(), data_buffer.protocol().0, data_buffer.header_checksum(), data_buffer.source(), data_buffer.destination(), data_buffer.payload_len().unwrap(), ) } #[allow(clippy::type_complexity)] #[inline(never)] fn etherparse_get_functions_not_inlined( data_buffer: ðerparse::Ipv4HeaderSlice, ) -> ( u8, u8, u8, u8, u16, u16, bool, bool, u16, u8, u8, u16, [u8; 4], [u8; 4], u16, ) { ( data_buffer.version(), data_buffer.ihl(), data_buffer.dcp().value(), data_buffer.ecn().value(), data_buffer.total_len(), data_buffer.identification(), data_buffer.dont_fragment(), data_buffer.more_fragments(), data_buffer.fragments_offset().value(), data_buffer.ttl(), data_buffer.protocol().0, data_buffer.header_checksum(), data_buffer.source(), data_buffer.destination(), data_buffer.payload_len().unwrap(), ) } pub fn ipv4(c: &mut Criterion) { let mut group = c.benchmark_group("ipv4"); group.throughput(Throughput::Bytes(random_ipv4().len() as u64)); group.bench_function("mutnet: new", |b| { b.iter_batched_ref( random_ipv4, |data| { let result = &parse_ipv4(std::hint::black_box(data)); std::hint::black_box(result); }, BatchSize::SmallInput, ); }); group.bench_function("etherparse: new", |b| { b.iter_batched_ref( random_ipv4, |data| { let result = &parse_ipv4_etherparse(std::hint::black_box(data)); std::hint::black_box(result); }, BatchSize::SmallInput, ); }); group.bench_function("mutnet: new + get functions inlined", |b| { b.iter_batched_ref( random_ipv4, |data| { let buffer = DataBuffer::<_, Ipv4>::parse_ipv4_alone( std::hint::black_box(data), 0, false, ) .unwrap(); let mut result = &mut mutnet_get_functions_inlined(&buffer); std::hint::black_box(&mut result); }, BatchSize::SmallInput, ); }); group.bench_function("etherparse: new + get functions inlined", |b| { b.iter_batched_ref( random_ipv4, |data| { let ether_slice = etherparse::Ipv4HeaderSlice::from_slice(std::hint::black_box(data)).unwrap(); let mut result = &mut etherparse_get_functions_inlined(ðer_slice); std::hint::black_box(&mut result); }, BatchSize::SmallInput, ); }); group.bench_function("mutnet: new + get functions not inlined", |b| { b.iter_batched_ref( random_ipv4, |data| { let buffer = DataBuffer::<_, Ipv4>::parse_ipv4_alone( std::hint::black_box(data), 0, false, ) .unwrap(); let mut result = &mut mutnet_get_functions_not_inlined(&buffer); std::hint::black_box(&mut result); }, BatchSize::SmallInput, ); }); group.bench_function("etherparse: new + get functions not inlined", |b| { b.iter_batched_ref( random_ipv4, |data| { let ether_slice = etherparse::Ipv4HeaderSlice::from_slice(std::hint::black_box(data)).unwrap(); let mut result = &mut etherparse_get_functions_not_inlined(ðer_slice); std::hint::black_box(&mut result); }, BatchSize::SmallInput, ); }); group.finish(); } criterion_group!(benches, ipv4); criterion_main!(benches);