Skip to main content

max / quasi

Say where the terminal frame's allocations go `QUASI_TUI_BREAKDOWN=1` under `--features count` splits the terminal column by difference: the hoisted buffer's own cost, the frame with the description already built, the same draw into a one-row viewport, the same draw into one tall enough to hold everything, and the webview over the same tree as a control. At 200 rows, of 15795 allocations a frame: the buffer reset is 0, the rebuild is 5418, a one-row viewport still costs 3628, and eight times the viewport height buys only 40% more. So 57% is data-proportional work done before anything is clipped, and the webview emits the whole table for 1447. Answers GoingsOn fc76b1ce, and bears on 2cff4a3d's assumption that the terminal has little to gain from a compiled path.
Author: Max Johnson <me@maxj.phd> · 2026-09-03 13:02 UTC
Signed with PGP, not checked
Commit: 71c879423186c7934c1b1dedd8eff9ef426ecf04
Parent: f6edde4
1 file changed, +77 insertions, -0 deletions
@@ -13,6 +13,13 @@
13 13 //! cargo run --release -p quasi-bench --features count # allocations per render
14 14 //! ```
15 15 //!
16 + //! And one diagnostic, off unless asked for, which attributes the terminal
17 + //! column's allocations between the rebuild, the pre-clip walk and the drawing:
18 + //!
19 + //! ```text
20 + //! QUASI_TUI_BREAKDOWN=1 cargo run --release -p quasi-bench --features count
21 + //! ```
22 + //!
16 23 //! Release, always. A debug build measures `opt-level = 1` and answers a
17 24 //! question nobody asked.
18 25 //!
@@ -253,6 +260,76 @@
253 260 immediate::frame(&ctx, &egui_renderer, black_box(&drawn), &mut view);
254 261 });
255 262
263 + // Where the terminal frame's allocations go, by difference rather than
264 + // by profiler. Off unless asked for, because it is a diagnostic about
265 + // one column and not part of the table.
266 + //
267 + // Each row of it isolates one candidate. `reset` is the hoisted
268 + // buffer's own cost. `draw` is the frame with the description already
269 + // built, so `terminal` minus `draw` is the rebuild. `h1` is the same
270 + // draw into a one-row viewport, which is everything that happens before
271 + // anything is clipped. `h400` is a viewport tall enough to hold the
272 + // whole table, so `h400` minus `h1` is the drawing itself. `webview` is
273 + // the control: the same prebuilt tree emitted in full, by a renderer
274 + // with no viewport to clip against.
275 + //
276 + // See GoingsOn `fc76b1ce` for what it answered.
277 + if std::env::var("QUASI_TUI_BREAKDOWN").is_ok() {
278 + let prebuilt_pane = fixture::pane(&rows);
279 +
280 + // Draw only: the same frame with the description already built.
281 + let mut b1 = Buffer::empty(TERMINAL);
282 + let draw_only = measure(|| {
283 + b1.reset();
284 + tui.node(black_box(&prebuilt_pane), &View::new(), TERMINAL, &mut b1);
285 + black_box(&b1);
286 + });
287 +
288 + // The reset alone, with no drawing at all.
289 + let mut b2 = Buffer::empty(TERMINAL);
290 + let reset_only = measure(|| {
291 + b2.reset();
292 + black_box(&b2);
293 + });
294 +
295 + // A viewport eight times taller. If the count barely moves, the
296 + // rows past the fold are already being paid for.
297 + let tall = Rect {
298 + height: 400,
299 + ..TERMINAL
300 + };
301 + let mut b3 = Buffer::empty(tall);
302 + let tall_draw = measure(|| {
303 + b3.reset();
304 + tui.node(black_box(&prebuilt_pane), &View::new(), tall, &mut b3);
305 + black_box(&b3);
306 + });
307 +
308 + // A viewport one row tall. If the count barely moves down, the
309 + // walk is not clipped at all.
310 + let short = Rect {
311 + height: 1,
312 + ..TERMINAL
313 + };
314 + let mut b4 = Buffer::empty(short);
315 + let short_draw = measure(|| {
316 + b4.reset();
317 + tui.node(black_box(&prebuilt_pane), &View::new(), short, &mut b4);
318 + black_box(&b4);
319 + });
320 +
321 + // The webview over the same prebuilt tree, as the control: it has
322 + // no viewport and must pay per row.
323 + let webview_draw = measure(|| {
324 + black_box(webview.fragment(black_box(&prebuilt_pane)));
325 + });
326 +
327 + println!(
328 + " BREAKDOWN {size:>4} rows: draw {draw_only}, reset {reset_only}, \
329 + h400 {tall_draw}, h1 {short_draw}, webview {webview_draw}"
330 + );
331 + }
332 +
256 333 let compiled = measure_compiled(&webview, &rows, &screen);
257 334
258 335 println!(