diff --git a/Cargo.toml b/Cargo.toml index 8d474f73..cec2d6df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -80,10 +80,18 @@ all-features = true cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"] rustdoc-args = ["--cfg", "docsrs"] +[[bench]] +name = "barchart" +harness = false + [[bench]] name = "block" harness = false +[[bench]] +name = "list" +harness = false + [[bench]] name = "paragraph" harness = false @@ -92,10 +100,6 @@ harness = false name = "sparkline" harness = false -[[bench]] -name = "list" -harness = false - [[example]] name = "barchart" diff --git a/benches/barchart.rs b/benches/barchart.rs new file mode 100644 index 00000000..7cd84d50 --- /dev/null +++ b/benches/barchart.rs @@ -0,0 +1,73 @@ +use criterion::{criterion_group, criterion_main, Bencher, BenchmarkId, Criterion}; +use rand::Rng; +use ratatui::{ + buffer::Buffer, + layout::Rect, + prelude::Direction, + widgets::{Bar, BarChart, BarGroup, Widget}, +}; + +/// Benchmark for rendering a barchart. +pub fn barchart(c: &mut Criterion) { + let mut group = c.benchmark_group("barchart"); + let mut rng = rand::thread_rng(); + + for data_count in [64, 256, 2048] { + let data: Vec = (0..data_count) + .map(|i| { + Bar::default() + .label(format!("B{i}").into()) + .value(rng.gen_range(0..data_count)) + }) + .collect(); + + let bargroup = BarGroup::default().bars(&data); + + // Render a basic barchart + group.bench_with_input( + BenchmarkId::new("render", data_count), + &BarChart::default().data(bargroup.clone()), + render, + ); + + // Render an horizontal barchart + group.bench_with_input( + BenchmarkId::new("render_horizontal", data_count), + &BarChart::default() + .direction(Direction::Horizontal) + .data(bargroup.clone()), + render, + ); + + // Render a barchart with multiple groups + group.bench_with_input( + BenchmarkId::new("render_grouped", data_count), + &BarChart::default() + // We call `data` multiple time to add multiple groups. + // This is not a duplicated call. + .data(bargroup.clone()) + .data(bargroup.clone()) + .data(bargroup.clone()), + render, + ); + } + + group.finish(); +} + +/// Render the widget in a classical size buffer +fn render(bencher: &mut Bencher, barchart: &BarChart) { + 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( + || barchart.clone(), + |bench_barchart| { + bench_barchart.render(buffer.area, &mut buffer); + }, + criterion::BatchSize::LargeInput, + ) +} + +criterion_group!(benches, barchart); +criterion_main!(benches);