use bgpkit_parser::BgpkitParser; use bzip2::bufread::BzDecoder; use criterion::{black_box, criterion_group, criterion_main, Criterion}; use flate2::bufread::GzDecoder; use std::fs::File; use std::io::{BufReader, Read}; use std::time::Duration; mod data_source; fn preload_min_for_n_entries(input_reader: R, n: usize) -> Vec { struct CopyReader<'a, R> { input: R, copy: &'a mut Vec, } impl<'a, R: Read> Read for CopyReader<'a, R> { fn read(&mut self, buf: &mut [u8]) -> std::io::Result { let bytes_read = self.input.read(buf)?; self.copy.extend_from_slice(&buf[..bytes_read]); Ok(bytes_read) } } let mut buffer = Vec::new(); let parser = BgpkitParser::from_reader(CopyReader { input: input_reader, copy: &mut buffer, }); parser.into_record_iter().take(n).for_each(drop); buffer } /// Since we uncompress the input data first, put a hard limit on the number of records so we don't /// use up too much memory. const RECORD_LIMIT: usize = 100_000; pub fn criterion_benchmark(c: &mut Criterion) { let update_data = data_source::test_data_file("update-example.gz"); let rib_data = data_source::test_data_file("rib-example-small.bz2"); let updates_reader = BufReader::new(File::open(update_data).unwrap()); let rib_reader = BufReader::new(File::open(rib_data).unwrap()); println!("Decompressing input data and loading into memory..."); let updates = preload_min_for_n_entries(GzDecoder::new(updates_reader), RECORD_LIMIT); let rib_dump = preload_min_for_n_entries(BzDecoder::new(rib_reader), RECORD_LIMIT); println!("Required {} bytes to store updates", updates.len()); println!("Required {} bytes to store rib table dump", rib_dump.len()); c.bench_function("updates into_record_iter", |b| { b.iter(|| { let mut reader = black_box(&updates[..]); BgpkitParser::from_reader(&mut reader) .into_record_iter() .take(RECORD_LIMIT) .for_each(|x| { black_box(x); }); }) }); c.bench_function("updates into_elem_iter", |b| { b.iter(|| { let mut reader = black_box(&updates[..]); BgpkitParser::from_reader(&mut reader) .into_elem_iter() .take(RECORD_LIMIT) .for_each(|x| { black_box(x); }); }) }); c.bench_function("rib into_record_iter", |b| { b.iter(|| { let mut reader = black_box(&rib_dump[..]); BgpkitParser::from_reader(&mut reader) .into_record_iter() .take(RECORD_LIMIT) .for_each(|x| { black_box(x); }); }) }); c.bench_function("rib into_elem_iter", |b| { b.iter(|| { let mut reader = black_box(&rib_dump[..]); BgpkitParser::from_reader(&mut reader) .into_elem_iter() .take(RECORD_LIMIT) .for_each(|x| { black_box(x); }); }) }); } criterion_group! { name = benches; config = Criterion::default().measurement_time(Duration::from_secs(30)); targets = criterion_benchmark } criterion_main!(benches);