use criterion::{Bencher, Criterion, criterion_group, criterion_main};
use syntect::parsing::{SyntaxSet, SyntaxReference, ScopeStack};
use syntect::highlighting::{ThemeSet, Theme};
use syntect::easy::HighlightLines;
use syntect::html::highlighted_html_for_string;
use std::str::FromStr;
use std::fs::File;
use std::io::Read;
fn do_highlight(s: &str, syntax_set: &SyntaxSet, syntax: &SyntaxReference, theme: &Theme) -> usize {
let mut h = HighlightLines::new(syntax, theme);
let mut count = 0;
for line in s.lines() {
let regions = h.highlight(line, syntax_set);
count += regions.len();
}
count
}
fn highlight_file(b: &mut Bencher, file: &str) {
let path = match file {
"highlight_test.erb" => "testdata/highlight_test.erb",
"InspiredGitHub.tmTheme" => "testdata/InspiredGitHub.tmtheme/InspiredGitHub.tmTheme",
"Ruby.sublime-syntax" => "testdata/Packages/Ruby/Ruby.sublime-syntax",
"jquery.js" => "testdata/jquery.js",
"parser.rs" => "testdata/parser.rs",
"scope.rs" => "src/parsing/scope.rs",
_ => panic!("Unknown test file {}", file),
};
let ss = SyntaxSet::load_defaults_nonewlines();
let ts = ThemeSet::load_defaults();
let syntax = ss.find_syntax_for_file(path).unwrap().unwrap();
let mut f = File::open(path).unwrap();
let mut s = String::new();
f.read_to_string(&mut s).unwrap();
b.iter(|| {
do_highlight(&s, &ss, syntax, &ts.themes["base16-ocean.dark"])
});
}
fn stack_matching(b: &mut Bencher) {
let s = "source.js meta.group.js meta.group.js meta.block.js meta.function-call.method.js meta.group.js meta.object-literal.js meta.block.js meta.function-call.method.js meta.group.js variable.other.readwrite.js";
let stack = ScopeStack::from_str(s).unwrap();
let selector = ScopeStack::from_str("source meta.function-call.method").unwrap();
b.iter(|| {
selector.does_match(stack.as_slice())
});
}
fn highlight_html(b: &mut Bencher) {
let ss = SyntaxSet::load_defaults_newlines();
let ts = ThemeSet::load_defaults();
let path = "testdata/parser.rs";
let syntax = ss.find_syntax_for_file(path).unwrap().unwrap();
let mut f = File::open(path).unwrap();
let mut s = String::new();
f.read_to_string(&mut s).unwrap();
b.iter(|| {
highlighted_html_for_string(&s, &ss, syntax, &ts.themes["base16-ocean.dark"])
});
}
fn highlighting_benchmark(c: &mut Criterion) {
c.bench_function("stack_matching", stack_matching);
c.bench_function("highlight_html", highlight_html);
c.bench_function_over_inputs(
"highlight",
|b, s| highlight_file(b, s),
vec![
"highlight_test.erb",
"InspiredGitHub.tmTheme",
"Ruby.sublime-syntax",
"jquery.js",
"parser.rs",
"scope.rs",
],
);
}
criterion_group! {
name = benches;
config = Criterion::default().sample_size(10);
targets = highlighting_benchmark
}
criterion_main!(benches);