#[macro_use]
extern crate criterion;
extern crate glitter_lang;
use glitter_lang::ast::{Color, CompleteStyle, Delimiter, Expression, Name, Style, Tree};
use glitter_lang::git::Stats;
use glitter_lang::interpreter::Interpreter;
use criterion::{Bencher, Criterion, Fun};
fn stats() -> Stats {
Stats {
untracked: 1,
added_staged: 1,
modified: 1,
modified_staged: 1,
renamed: 1,
deleted: 1,
deleted_staged: 1,
ahead: 1,
behind: 1,
conflicts: 1,
stashes: 1,
branch: "master".to_string(),
remote: "origin/master".to_string(),
}
}
fn empty_stats(c: &mut Criterion) {
use Expression::*;
use Name::*;
let empty: Stats = Default::default();
let expression = Tree(vec![Group {
d: Delimiter::Square,
sub: Tree(vec![
Named {
name: Modified,
sub: Tree::new(),
},
Named {
name: Added,
sub: Tree::new(),
},
Named {
name: Renamed,
sub: Tree::new(),
},
Named {
name: Deleted,
sub: Tree::new(),
},
]),
}]);
let mut interpreter = Interpreter::new(empty, true, true);
c.bench_function("default stats \"[MARD]\"", move |b| {
let mut out = Vec::with_capacity(128);
b.iter(|| {
out.clear();
let _ = interpreter.evaluate(&expression, &mut out);
})
});
}
fn real_world(c: &mut Criterion) {
use glitter_lang::parser::parse;
let tree = parse(r"[#g*(b)#r(B(#~('..')))#w(\(#~*(+('↑')-('↓')))<#g(MARD)#r(maud)>{#m*_(h('@'))})]' '#b*('\w')'\n '").expect("failed to parse example");
let mut i = Interpreter::new(stats(), true, true);
c.bench_function("Real world \"$GIT_FMT\" example", move |b| {
let mut out = Vec::with_capacity(256);
b.iter(|| {
out.clear();
let _ = i.evaluate(&tree, &mut out);
})
});
}
fn nested_named(c: &mut Criterion) {
use Expression::*;
use Name::*;
macro_rules! tree {
($expr:tt, $($tail:tt),*) => {{
Tree(vec![Named {
name: $expr,
sub: tree![$($tail),*]
}])
}};
($expr:tt) => {{
Tree(vec![Named {
name: $expr,
sub: Tree::default(),
}])
}};
}
macro_rules! depth {
($($tail:tt),+) => {{
|b: &mut Bencher, s: &Stats| {
let mut interpreter = Interpreter::new(s.clone(), true, true);
let e = tree![$($tail),+];
let mut out = Vec::with_capacity(128);
b.iter(|| {
out.clear();
let _ = interpreter.evaluate(&e, &mut out);
});
}
}};
}
c.bench_functions(
"nested named",
vec![
Fun::new("depth 1", depth![Modified]),
Fun::new("depth 2", depth![Modified, Added]),
Fun::new("depth 3", depth![Modified, Added, Untracked]),
Fun::new("depth 4", depth![Modified, Added, Untracked, Deleted]),
Fun::new(
"depth 5",
depth![Modified, Added, Untracked, Deleted, Branch],
),
],
stats(),
);
}
fn tree_length(c: &mut Criterion) {
use Expression::*;
use Name::*;
macro_rules! length_n {
($n:expr) => {
|b: &mut Bencher, s: &Stats| {
let e = Tree(
std::iter::repeat(Named {
name: Deleted,
sub: Tree::new(),
})
.take($n)
.collect(),
);
let mut i = Interpreter::new(s.clone(), true, true);
let mut out = Vec::with_capacity(128);
b.iter(|| {
out.clear();
let _ = i.evaluate(&e, &mut out);
});
}
};
}
c.bench_functions(
"tree length",
vec![
Fun::new("length 2", length_n!(2)),
Fun::new("length 4", length_n!(4)),
Fun::new("length 8", length_n!(8)),
Fun::new("length 16", length_n!(16)),
Fun::new("length 32", length_n!(32)),
],
stats(),
);
}
fn interpret_style(c: &mut Criterion) {
use Color::*;
use Expression::*;
use Style::*;
macro_rules! style {
($style:expr, $content:expr) => {
|b: &mut Bencher, s: &Stats| {
let styles = Tree(vec![Format {
style: $style,
sub: $content,
}]);
let mut i = Interpreter::new(s.clone(), true, true);
let mut out = Vec::with_capacity(128);
b.iter(|| {
out.clear();
let _ = i.evaluate(&styles, &mut out);
})
}
};
}
fn test() -> Tree {
Tree(vec![Literal("test".into())])
}
fn make_style(ss: &[Style]) -> CompleteStyle {
ss.iter().collect()
}
c.bench_functions(
"Interpreting Style",
vec![
Fun::new("Empty style", style!(Default::default(), Tree::new())),
Fun::new("Default style", style!(Default::default(), test())),
Fun::new("Bold", style!(make_style(&[Bold]), test())),
Fun::new(
"Bold, Underline text",
style!(make_style(&[Bold, Underline]), test()),
),
Fun::new(
"Bold, Underline, Italic text",
style!(make_style(&[Bold, Underline, Italic]), test()),
),
Fun::new(
"Colored Text",
style!(make_style(&[Fg(Red), Bg(White)]), test()),
),
Fun::new(
"Colored Underline Text",
style!(make_style(&[Fg(Red), Bg(White), Underline]), test()),
),
],
stats(),
);
}
criterion_group!(
interpreter,
real_world,
empty_stats,
nested_named,
tree_length,
interpret_style,
);
criterion_main!(interpreter);