rustyphoenixmicrobenchmark 1.3.0

Toolset for function micro-benchmarking. Rust equivalent of C++ [PhoenixMicroBenchmark](https://gitlab.in2p3.fr/CTA-LAPP/PHOENIX_LIBS2/test-benchmark/PhoenixMicroBenchmark)
Documentation
/***************************************
	Auteur : Pierre Aubert
	Mail : pierre.aubert@lapp.in2p3.fr
	Licence : CeCILL-C
****************************************/

pub use std::time::Instant;
pub use std::cmp::Ordering;

mod pellapsedtime;
mod macro_function_timer;
mod pfunctiontimer;

pub use crate::pellapsedtime::PEllapsedTime;
pub use crate::pfunctiontimer::PFunctionTimer;

///A macro to call properly the evaluation function for you
/// # Parameters
/// - `vec_ellapsed_time` : vector of ellapsed time to be completed
/// - `nb_test_perf` : number of performance test
/// - `nb_call_per_test` : number of calls per performance test
/// - `nb_element` : number of elements processed
/// - `func_call_bench` : function to be benchmarked
/// # Errors
/// Panic if nb_test_perf == 0
#[macro_export] macro_rules! phoenix_micro_benchmark_ns {
	($vec_ellapsed_time:ident, $param_nb_test_perf:expr, $param_nb_call_per_test:expr, $nb_element:expr, $func_call_bench:expr) => {
		{
			if $param_nb_test_perf == 0 {
				panic!("phoenix_micro_benchmark_ns: nb_test_perf cannot be 0");
			}
			let mut vec_time_ns: Vec<f64> = vec![];
			for _ in 0..$param_nb_test_perf {
				//We have to check if it is really nanoseconds
				// let begin_time_ns: i64 = chrono::offset::Local::now().timestamp() as i64;
				let begin_time_ns = Instant::now();
				for _ in 0..$param_nb_call_per_test {
					$func_call_bench;
				}
				// let ellapsed_time_ns: f64 = (((chrono::offset::Local::now().timestamp() as i64) - begin_time_ns) as f64)/(nb_call_per_test as f64);
				let ellapsed_time_ns: f64 = (begin_time_ns.elapsed().as_nanos()/($param_nb_call_per_test as u128) ) as f64;
				vec_time_ns.push(ellapsed_time_ns);
			}
			//The horrible ordering of a vector of f64
			vec_time_ns.sort_by(|a, b| if a < b {
					Ordering::Less
				}else if a == b {
					Ordering::Equal
				}else{
					Ordering::Greater
				}
			);	//Let's sort the vector of ellapsed times in nanoseconds
			// println!("micro_benchmark_ns : vec_time_ns : {:?}", vec_time_ns);
			$vec_ellapsed_time.push(PEllapsedTime::new(
				$nb_element,
				vec_time_ns[0],
				*vec_time_ns.last().unwrap(),
				vec_time_ns[vec_time_ns.iter().count()/2],
			));
		};
	};
}

#[cfg(test)]
mod tests {
	use super::*;
	use crate::pellapsedtime::PEllapsedTime;
	
	///A Hadamard product to test the micro_benchmark function
	/// # Parameters
	/// - `vec_res` : output vector of result
	/// - `vec_x` : vector of values
	/// - `vec_y` : vector of values
	fn hadamard_product(vec_res: &mut Vec<f32>, vec_x: &Vec<f32>, vec_y: &Vec<f32>){
		*vec_res = vec_x.into_iter().zip(vec_y)
			.map(|(x, y)| x * y)
			.collect::<Vec<_>>();
	}
	///Test the micro benchmark call in nanoseconds
	#[test]
	fn test_phoenix_micro_benchmark_ns(){
		let nb_value = 1000;
		let vec_x: Vec<f32> = vec![1.0; nb_value];
		let vec_y: Vec<f32> = vec![2.0; nb_value];
		let mut vec_res: Vec<f32> = vec![0.0; nb_value];
		
		let mut vec_ellapsed_time: Vec<PEllapsedTime> = vec![];
		phoenix_micro_benchmark_ns!(vec_ellapsed_time, 100, 100, nb_value, hadamard_product(&mut vec_res, &vec_x, &vec_y));
		println!("{:?}", vec_ellapsed_time);
		// panic!("just to see results");
	}
}