improved performance and benchmarking

This commit is contained in:
Simon Gardling
2022-05-04 10:06:38 -04:00
parent 452820ce26
commit d57609217a
3 changed files with 33 additions and 26 deletions

View File

@@ -4,10 +4,13 @@
#[allow(unused_imports)] #[allow(unused_imports)]
use parsing::suggestions::split_function_chars; use parsing::suggestions::split_function_chars;
#[allow(unused_imports)]
use std::time::Duration;
use std::{fs::File, os::raw::c_int, path::Path}; use std::{fs::File, os::raw::c_int, path::Path};
use criterion::profiler::Profiler; use criterion::profiler::Profiler;
use criterion::Criterion; #[allow(unused_imports)]
use criterion::{BenchmarkId, Criterion};
use criterion_macro::criterion; use criterion_macro::criterion;
use pprof::ProfilerGuard; use pprof::ProfilerGuard;
@@ -47,8 +50,11 @@ impl<'a> Profiler for FlamegraphProfiler<'a> {
} }
} }
#[allow(dead_code)] // this infact IS used by benchmarks
fn custom_criterion() -> Criterion { fn custom_criterion() -> Criterion {
Criterion::default().with_profiler(FlamegraphProfiler::new(100)) Criterion::default()
// .with_profiler(FlamegraphProfiler::new(100))
.warm_up_time(Duration::from_millis(250))
} }
#[criterion(custom_criterion())] #[criterion(custom_criterion())]
@@ -71,11 +77,17 @@ fn split_function_bench(c: &mut Criterion) {
.map(|a| a.chars().collect::<Vec<char>>()) .map(|a| a.chars().collect::<Vec<char>>())
.collect::<Vec<Vec<char>>>(); .collect::<Vec<Vec<char>>>();
c.bench_function("split_function", |b| { let mut group = c.benchmark_group("split_function");
b.iter(|| { for entry in data_chars {
data_chars.iter().for_each(|a| { group.bench_with_input(
split_function_chars(a); BenchmarkId::new("split_function", entry.iter().collect::<String>()),
}) &entry,
}) |b, i| {
}); b.iter(|| {
split_function_chars(i);
})
},
);
}
group.finish();
} }

View File

@@ -129,22 +129,10 @@ fn prettyify_function_str(func: &str) -> String {
} }
pub const VALID_VARIABLES: [char; 5] = ['x', 'X', 'e', 'E', 'π']; pub const VALID_VARIABLES: [char; 5] = ['x', 'X', 'e', 'E', 'π'];
const LETTERS: [char; 52] = [
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
];
const NUMBERS: [char; 10] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
#[inline] #[inline]
pub fn is_variable(c: &char) -> bool { VALID_VARIABLES.contains(&c) } pub fn is_variable(c: &char) -> bool { VALID_VARIABLES.contains(&c) }
#[inline]
pub fn is_letter(c: &char) -> bool { LETTERS.contains(&c) }
#[inline]
pub fn is_number(c: &char) -> bool { NUMBERS.contains(&c) }
/// Adds asterisks where needed in a function /// Adds asterisks where needed in a function
pub fn process_func_str(function_in: &str) -> String { pub fn process_func_str(function_in: &str) -> String {
if function_in.is_empty() { if function_in.is_empty() {

View File

@@ -1,4 +1,4 @@
use crate::parsing::{is_letter, is_number, is_variable}; use crate::parsing::is_variable;
pub const HINT_EMPTY: Hint = Hint::Single("x^2"); pub const HINT_EMPTY: Hint = Hint::Single("x^2");
const HINT_CLOSED_PARENS: Hint = Hint::Single(")"); const HINT_CLOSED_PARENS: Hint = Hint::Single(")");
@@ -40,7 +40,6 @@ pub fn split_function_chars(chars: &[char]) -> Vec<String> {
// Buffer used to store data ready to be appended // Buffer used to store data ready to be appended
let mut buffer: Vec<&char> = Vec::with_capacity(chars.len()); let mut buffer: Vec<&char> = Vec::with_capacity(chars.len());
#[derive(Default)]
struct BoolSlice { struct BoolSlice {
closing_parens: bool, closing_parens: bool,
number: bool, number: bool,
@@ -59,17 +58,25 @@ pub fn split_function_chars(chars: &[char]) -> Vec<String> {
fn is_number(&self) -> bool { self.number && !self.masked_num } fn is_number(&self) -> bool { self.number && !self.masked_num }
} }
let mut prev_char: BoolSlice = BoolSlice::default(); let mut prev_char: BoolSlice = BoolSlice {
closing_parens: false,
number: false,
letter: false,
variable: false,
masked_num: false,
masked_var: false,
exists: false,
};
for c in chars { for c in chars {
// Set data about current character // Set data about current character
let mut curr_c = { let mut curr_c = {
let isnumber = is_number(c); let isnumber = c.is_ascii_digit();
let isvariable = is_variable(c); let isvariable = is_variable(c);
BoolSlice { BoolSlice {
closing_parens: c == &')', closing_parens: c == &')',
number: isnumber, number: isnumber,
letter: is_letter(c), letter: c.is_ascii_alphabetic(),
variable: isvariable, variable: isvariable,
masked_num: match isnumber { masked_num: match isnumber {
true => prev_char.masked_num, true => prev_char.masked_num,