#![feature(custom_test_frameworks)] #![test_runner(criterion::runner)] #[allow(unused_imports)] use parsing::split_function_chars; #[allow(unused_imports)] use std::time::Duration; use std::{fs::File, os::raw::c_int, path::Path}; use criterion::profiler::Profiler; #[allow(unused_imports)] use criterion::{BenchmarkId, Criterion}; use criterion_macro::criterion; use pprof::ProfilerGuard; pub struct FlamegraphProfiler<'a> { frequency: c_int, active_profiler: Option>, } impl<'a> FlamegraphProfiler<'a> { #[allow(dead_code)] pub fn new(frequency: c_int) -> Self { FlamegraphProfiler { frequency, active_profiler: None, } } } impl<'a> Profiler for FlamegraphProfiler<'a> { fn start_profiling(&mut self, _benchmark_id: &str, _benchmark_dir: &Path) { self.active_profiler = Some(ProfilerGuard::new(self.frequency).unwrap()); } fn stop_profiling(&mut self, _benchmark_id: &str, benchmark_dir: &Path) { std::fs::create_dir_all(benchmark_dir).unwrap(); let flamegraph_path = benchmark_dir.join("flamegraph.svg"); let flamegraph_file = File::create(&flamegraph_path) .expect("File system error while creating flamegraph.svg"); if let Some(profiler) = self.active_profiler.take() { profiler .report() .build() .unwrap() .flamegraph(flamegraph_file) .expect("Error writing flamegraph"); } } } #[allow(dead_code)] // this infact IS used by benchmarks fn custom_criterion() -> Criterion { Criterion::default() .warm_up_time(Duration::from_millis(250)) .sample_size(1000) } #[allow(dead_code)] // this infact IS used by benchmarks fn custom_criterion_flamegraph() -> Criterion { custom_criterion().with_profiler(FlamegraphProfiler::new(100)) } #[criterion(custom_criterion())] fn mutli_split_function(c: &mut Criterion) { let data_chars = vec![ "sin(x)cos(x)", "x^2", "2x", "log10(x)", "E^x", "xxxxx", "xsin(x)", "(2x+1)(3x+1)", "x**2", "pipipipipipix", "pi(2x+1)", "(2x+1)pi", ] .iter() .map(|a| a.chars().collect::>()) .collect::>>(); let mut group = c.benchmark_group("split_function"); for entry in data_chars { group.bench_function(entry.iter().collect::(), |b| { b.iter(|| { split_function_chars(&entry, parsing::suggestions::SplitType::Multiplication); }) }); } group.finish(); } // #[criterion(custom_criterion_flamegraph())] // fn single_split_function(c: &mut Criterion) { // let data_chars = "(2x+1)(3x+1)".chars().collect::>(); // c.bench_function("split_function", |b| { // b.iter(|| { // split_function_chars(&data_chars); // }); // }); // }