diff --git a/Cargo.toml b/Cargo.toml index 24d60104..1a44820c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,6 +67,10 @@ harness = false name = "block" harness = false +[[bench]] +name = "list" +harness = false + [[example]] name = "barchart" diff --git a/benches/list.rs b/benches/list.rs new file mode 100644 index 00000000..b551ab02 --- /dev/null +++ b/benches/list.rs @@ -0,0 +1,73 @@ +use criterion::{criterion_group, criterion_main, BatchSize, Bencher, BenchmarkId, Criterion}; +use ratatui::{ + buffer::Buffer, + layout::Rect, + widgets::{List, ListItem, ListState, StatefulWidget, Widget}, +}; + +/// Benchmark for rendering a list. +/// It only benchmarks the render with a different amount of items. +pub fn list(c: &mut Criterion) { + let mut group = c.benchmark_group("list"); + + for line_count in [64, 2048, 16384] { + let lines: Vec = (0..line_count) + .map(|_| ListItem::new(fakeit::words::sentence(10))) + .collect(); + + // Render default list + group.bench_with_input( + BenchmarkId::new("render", line_count), + &List::new(lines.clone()), + render, + ); + + // Render with an offset to the middle of the list and a selected item + group.bench_with_input( + BenchmarkId::new("render_scroll_half", line_count), + &List::new(lines.clone()).highlight_symbol(">>"), + |b, list| { + render_stateful( + b, + list, + ListState::default() + .with_offset(line_count / 2) + .with_selected(Some(line_count / 2)), + ) + }, + ); + } + + group.finish(); +} + +/// render the list into a common size buffer +fn render(bencher: &mut Bencher, list: &List) { + let mut buffer = Buffer::empty(Rect::new(0, 0, 200, 50)); + // We use `iter_batched` to clone the value in the setup function. + // See https://github.com/ratatui-org/ratatui/pull/377. + bencher.iter_batched( + || list.to_owned(), + |bench_list| { + Widget::render(bench_list, buffer.area, &mut buffer); + }, + BatchSize::LargeInput, + ) +} + +/// render the list into a common size buffer with a state +fn render_stateful(bencher: &mut Bencher, list: &List, mut state: ListState) { + let mut buffer = Buffer::empty(Rect::new(0, 0, 200, 50)); + // We use `iter_batched` to clone the value in the setup function. + // See https://github.com/ratatui-org/ratatui/pull/377. + bencher.iter_batched( + || list.to_owned(), + |bench_list| { + StatefulWidget::render(bench_list, buffer.area, &mut buffer, &mut state); + }, + BatchSize::LargeInput, + ) +} + +criterion_group!(benches, list); +criterion_main!(benches);