use criterion::{black_box, criterion_group, criterion_main, Criterion};
use std::io::Write;
use tempfile::NamedTempFile;
use tess::line_index::LineIndex;
use tess::render::{count_rows, render_line, RenderOpts};
use tess::source::FileSource;
use tess::viewport::Viewport;
const LINE: &[u8] = b"the quick brown fox jumps over the lazy dog 0123456789\n";
fn make_big_input(target_bytes: usize) -> Vec<u8> {
let mut v = Vec::with_capacity(target_bytes + LINE.len());
while v.len() < target_bytes {
v.extend_from_slice(LINE);
}
v
}
fn bench_big_file_open(c: &mut Criterion) {
let bytes = make_big_input(10 * 1024 * 1024);
let mut tmp = NamedTempFile::new().unwrap();
tmp.write_all(&bytes).unwrap();
c.bench_function("big_file_open_10mb", |b| {
b.iter(|| {
let src = FileSource::open(tmp.path()).unwrap();
let mut idx = LineIndex::new();
idx.extend_to_end(&src);
black_box(idx.line_count());
});
});
}
fn bench_scroll_page(c: &mut Criterion) {
let bytes = make_big_input(1024 * 1024);
let mut tmp = NamedTempFile::new().unwrap();
tmp.write_all(&bytes).unwrap();
let src = FileSource::open(tmp.path()).unwrap();
let mut idx = LineIndex::new();
idx.extend_to_end(&src);
let mut viewport = Viewport::new(80, 24, String::from("bench"));
c.bench_function("scroll_page_compose_frame", |b| {
b.iter(|| {
let frame = viewport.frame(&src, &mut idx);
black_box(frame);
});
});
}
fn bench_regex_search(c: &mut Criterion) {
let bytes = make_big_input(2 * 1024 * 1024);
let re = regex::Regex::new(r"lazy\s+dog").unwrap();
c.bench_function("regex_search_2mb", |b| {
b.iter(|| {
let mut hits = 0usize;
for line in bytes.split(|&b| b == b'\n') {
if let Ok(s) = std::str::from_utf8(line) {
if re.is_match(s) {
hits += 1;
}
}
}
black_box(hits);
});
});
}
fn bench_render_line(c: &mut Criterion) {
let opts = RenderOpts { tab_width: 8, wrap: true, cols: 80, mode: tess::render::AnsiMode::Strict, ..Default::default() };
let line: &[u8] = b"a fairly long line with \t tabs and \x1b control bytes and \xff invalid \xfe utf8 to stress decoding";
c.bench_function("render_line_80cols", |b| {
b.iter(|| {
let rows = render_line(black_box(line), black_box(&opts), None);
black_box(rows.len());
});
});
c.bench_function("count_rows_80cols", |b| {
b.iter(|| {
let n = count_rows(black_box(line), black_box(&opts), None);
black_box(n);
});
});
}
fn bench_big_file_open_with_records(c: &mut Criterion) {
let bytes = make_big_input(10 * 1024 * 1024);
let mut tmp = NamedTempFile::new().unwrap();
tmp.write_all(&bytes).unwrap();
c.bench_function("big_file_open_10mb_with_records", |b| {
b.iter(|| {
let src = FileSource::open(tmp.path()).unwrap();
let mut idx = LineIndex::new();
idx.set_record_start(regex::bytes::Regex::new(r"^the").unwrap());
idx.extend_to_end(&src);
black_box(idx.record_count());
});
});
}
criterion_group!(benches,
bench_big_file_open,
bench_scroll_page,
bench_regex_search,
bench_render_line,
bench_big_file_open_with_records,
);
criterion_main!(benches);