//! Benchmark: CPU-side terminal-cell-instance building throughput. //! //! Measures how fast the renderer can produce `CellInstance` data for a //! fully-populated terminal grid without involving the GPU or a real window. //! //! Run with: //! ``` //! cargo run --bin bench_render --release //! ``` use std::time::Instant; use winiterm::terminal::Terminal; use winiterm::vt_parser::Parser; fn main() { const COLS: usize = 220; const ROWS: usize = 55; const FRAMES: usize = 5_000; const SCROLLBACK: usize = 1_000; // Fill the terminal with a mix of ASCII text and escape sequences. let mut terminal = Terminal::new(COLS, ROWS, SCROLLBACK); let mut parser = Parser::new(); // A line that exercises SGR colours and printable ASCII. let fill_line = format!( "\x1b[32mHello\x1b[0m \x1b[1;33mworld\x1b[0m! {}", "abcdefghijklmnopqrstuvwxyz0123456789 ".repeat(4) ); let fill_bytes = fill_line.as_bytes(); for _ in 0..ROWS { parser.parse(fill_bytes, &mut terminal); parser.parse(b"\r\n", &mut terminal); } // Simulate the CPU work done per frame: iterate all cells to count them. // (A real renderer would write CellInstance structs into a Vec here.) let cell_count = COLS * ROWS; let mut total: u64 = 0; let start = Instant::now(); for _ in 0..FRAMES { for idx in 0..cell_count { // Simulate the work of push_cell: read cell, inspect attrs. let cell = &terminal.screen[idx]; total = total.wrapping_add(cell.ch as u64); } } let elapsed = start.elapsed(); let _ = total; // prevent optimizer from eliding the loop let fps = FRAMES as f64 / elapsed.as_secs_f64(); let mcells_per_sec = (FRAMES as f64 * cell_count as f64) / elapsed.as_secs_f64() / 1_000_000.0; println!( "bench_render: {} frames × {}×{} cells → {:.0} fps ({:.0} Mcells/s) [{:.2?}]", FRAMES, COLS, ROWS, fps, mcells_per_sec, elapsed ); }