use std::time::SystemTime; use openpgp_cert_d as cert_d; use cert_d::CertD; use cert_d::Tag; fn main() -> std::result::Result<(), Box> { let args = std::env::args().collect::>(); let certd = if args.len() == 1 { CertD::new()? } else if args.len() == 2 { CertD::with_base_dir(&args[1])? } else { eprintln!("Usage: {} [CERTD]", args[0]); return Err("Invalid arguments".into()); }; let iter_fingerprint = certd.fingerprints(); let fingerprints = iter_fingerprint.collect::, _>>()?; eprintln!("Have {} certificates", fingerprints.len()); // Number of trials. const N: usize = 1000; let mut stat_one_trials: [u128; N] = [0; N]; let mut stat_one_tags: [Tag; N] = [Tag(0); N]; let mut tag_readdir_std_trials: [u128; N] = [0; N]; let mut tag_readdir_std_tags: [Tag; N] = [Tag(0); N]; let mut tag_probe_std_trials: [u128; N] = [0; N]; let mut tag_probe_std_tags: [Tag; N] = [Tag(0); N]; #[cfg(unix)] let mut tag_readdir_unix_trials: [u128; N] = [0; N]; #[cfg(unix)] let mut tag_readdir_unix_tags: [Tag; N] = [Tag(0); N]; #[cfg(unix)] let mut tag_probe_unix_trials: [u128; N] = [0; N]; #[cfg(unix)] let mut tag_probe_unix_tags: [Tag; N] = [Tag(0); N]; eprintln!("Running {} trials", N); for trial in 0..N { let start = SystemTime::now(); if let Ok(meta_data) = std::fs::metadata(certd.base_dir()) { stat_one_tags[trial] = Tag::try_from(meta_data).unwrap(); } let end = SystemTime::now(); stat_one_trials[trial] = end.duration_since(start).unwrap().as_nanos(); let start = SystemTime::now(); tag_readdir_std_tags[trial] = certd.tag_readdir_std(); let end = SystemTime::now(); tag_readdir_std_trials[trial] = end.duration_since(start).unwrap().as_nanos(); let start = SystemTime::now(); tag_probe_std_tags[trial] = certd.tag_probe_std(None); let end = SystemTime::now(); tag_probe_std_trials[trial] = end.duration_since(start).unwrap().as_nanos(); #[cfg(unix)] { let start = SystemTime::now(); tag_readdir_unix_tags[trial] = certd.tag_readdir_unix(); let end = SystemTime::now(); tag_readdir_unix_trials[trial] = end.duration_since(start).unwrap().as_nanos(); } #[cfg(unix)] { let start = SystemTime::now(); tag_probe_unix_tags[trial] = certd.tag_probe_unix(None); let end = SystemTime::now(); tag_probe_unix_trials[trial] = end.duration_since(start).unwrap().as_nanos(); } } let stat_one_mean: u128 = stat_one_trials.iter().sum::() / (N as u128); let summarize = |desc, mut trials: [u128; N]| { // Add thousand separators. let ts = |n: u128| { n.to_string() .as_bytes() .rchunks(3) .rev() .map(String::from_utf8_lossy) .collect::>() .join(",") }; eprintln!("{}:", desc); let mean: u128 = trials.iter().sum::() / (N as u128); trials.sort(); //eprintln!(" min: {} ns", ts(trials[0])); eprintln!(" 10%: {} ns", ts(trials[1 * N / 10])); eprintln!(" mean: {} ns", ts(mean)); eprintln!(" median: {} ns", ts(trials[5 * N / 10])); eprintln!(" 90%: {} ns", ts(trials[9 * N / 10])); //eprintln!(" max: {} ns", ts(trials[N - 1])); eprintln!("stat factor: {}", mean / stat_one_mean); }; summarize("stats_one", stat_one_trials); summarize("CertD::tag_readdir_std", tag_readdir_std_trials); summarize("CertD::tag_probe_std", tag_probe_std_trials); // Make sure the two implementations compute the same // tags. assert_eq!(tag_readdir_std_tags, tag_probe_std_tags); #[cfg(unix)] { summarize("CertD::tag_readdir_unix", tag_readdir_unix_trials); // Make sure the two implementations compute the same // tags. assert_eq!(tag_readdir_std_tags, tag_readdir_unix_tags); } #[cfg(unix)] { summarize("CertD::tag_probe_unix", tag_probe_unix_trials); assert_eq!(tag_readdir_std_tags, tag_probe_unix_tags); } Ok(()) }