#![allow(unused)] use bissel::*; use std::error::Error; use std::time::Instant; trait Benchmarkable: 'static + Clone + From + Message + PartialEq {} impl Benchmarkable for T where T: 'static + Clone + From + Message + PartialEq {} #[derive(Debug)] struct BenchmarkStats { payload_size: usize, iterations: usize, invalid_operations: usize, average_time_us: f64, min_time_us: f64, max_time_us: f64, } // USAGE: $ cargo run --release --example benchmark 100000 fn main() -> Result<(), Box> { let args: Vec = std::env::args().collect(); dbg!(args.len()); if args.len() != 2 { let emsg = format!("USAGE: cargo run --example --release "); panic!("{}", emsg); } let iterations = args[1].parse::().unwrap(); // Benchmark a single f32 value let f32_stats = benchmark_numeric::(iterations)?; println!("f32 stats: {:#?}", f32_stats); let collection_size = 100; let vec_f32_stats = benchmark_numeric_collections::(iterations, collection_size)?; println!("f32 collection stats, length: {:#?}", vec_f32_stats); Ok(()) } fn benchmark_numeric( iterations: usize, ) -> Result> { let mut host: Host = HostConfig::new("lo").build()?; host.start()?; println!("Host should be running in the background"); // Get the host up and running let node: Node = NodeConfig::new("BENCH_f32") .topic("benchmark_f32") .build() .unwrap(); let mut node = node.connect()?; let mut payload_size: usize = 0; let mut times: Vec = Vec::with_capacity(iterations); let mut invalid_ops: Vec = Vec::with_capacity(iterations); for i in 0..iterations { let val: T = rand::random::().into(); payload_size = std::mem::size_of_val(&val); let clone = val.clone(); let now = Instant::now(); // Publish and request a value from the host node.publish(clone)?; let result = node.request()?; let time = now.elapsed().as_micros(); if result == val { times.push(time); } else { invalid_ops.push(i); } } let stats = BenchmarkStats { payload_size, iterations, invalid_operations: invalid_ops.len(), average_time_us: times.iter().sum::() as f64 / (times.len() as f64), min_time_us: *times.iter().min().unwrap() as f64, max_time_us: *times.iter().max().unwrap() as f64, }; host.stop()?; Ok(stats) } fn benchmark_numeric_collections( iterations: usize, collection_size: usize, ) -> Result> { let mut host: Host = HostConfig::new("lo").build()?; host.start()?; println!("Host should be running in the background"); // Get the host up and running let node: Node> = NodeConfig::new("BENCH_f32") .topic("benchmark_f32") .build() .unwrap(); let mut node = node.connect()?; let mut payload_size: usize = 0; let mut times: Vec = Vec::with_capacity(iterations); let mut invalid_ops: Vec = Vec::with_capacity(iterations); for i in 0..iterations { let mut val: Vec = Vec::with_capacity(collection_size); for _ in 0..collection_size { val.push(rand::random::().into()); } payload_size = std::mem::size_of_val(&val[0]) * val.len(); let clone = val.to_owned().to_vec(); let now = Instant::now(); // Publish and request a value from the host node.publish(clone)?; let result = node.request()?; let time = now.elapsed().as_micros(); if result == val { times.push(time); } else { invalid_ops.push(i); } } let stats = BenchmarkStats { payload_size, iterations, invalid_operations: invalid_ops.len(), average_time_us: times.iter().sum::() as f64 / (times.len() as f64), min_time_us: *times.iter().min().unwrap() as f64, max_time_us: *times.iter().max().unwrap() as f64, }; host.stop()?; Ok(stats) }