Files
dev/docs/tui2/performance-testing.md
T
zeekay dae0dcad42 feat: rename code-rs to hanzo-dev and prepare for publication
🎯 Major directory restructure and publication preparation:

**Directory Rename:**
- Renamed code-rs/ → hanzo-dev/ for better branding alignment
- Updated all build scripts, GitHub workflows, and documentation
- Fixed all path references across the codebase

**Publication Setup:**
- Updated workspace version to 0.6.0 (production ready)
- Configured main CLI crate as 'hanzo-dev' (available on crates.io)
- Set publish = true for core crates (hanzo-core, hanzo-tui)
- Added proper package metadata (description, license, repository, etc.)
- Maintained internal crate names to minimize dependency changes

**Updated Components:**
- package.json build scripts now reference hanzo-dev/
- GitHub Actions workflows updated for new directory structure
- build-fast.sh and related scripts updated
- Documentation and README references updated
- All Cargo.toml manifests updated with publication metadata

**Publishing Strategy:**
- Main binary: hanzo-dev (new, available for publication)
- Core library: hanzo-core (existing name, ready to publish)
- TUI library: hanzo-tui (existing name, ready to publish)
- Avoids conflict with existing Hanzo AI infrastructure crates

This prepares the codebase for official publication to crates.io while
maintaining full compatibility with the existing build system and
providing clear branding as 'Hanzo Dev' CLI tool.
2026-01-14 16:49:45 -08:00

3.3 KiB
Raw Blame History

Performance testing (dev-tui2)

This doc captures a repeatable workflow for investigating dev-tui2 performance issues (especially high idle CPU and high CPU while streaming) and validating optimizations to the draw hot path.

Scope (this round)

The current focus is the transcript draw hot path, specifically the cost of repeatedly rendering the same visible transcript lines via Ratatui’s Line::render_ref (notably grapheme segmentation and span layout).

The intended mitigation is a rasterization cache: render a wrapped transcript Line into a row of Cells once, cache it, and on subsequent redraws copy cached cells into the frame buffer.

Key invariants:

  • The cache is width-scoped (invalidate on terminal width changes).
  • The cache stores base content only; selection highlight and copy affordances are applied after rendering, so they don’t pollute cached rows.

Roles

  • Human: runs dev-tui2 in an interactive terminal (e.g. Ghostty), triggers “idle” and “streaming” scenarios, and captures profiles.
  • Assistant (or a script): reads profile output and extracts hotspots and deltas.

Baseline setup

Build from a clean checkout:

cd hanzo-dev
cargo build -p dev-tui2

Run dev-tui2 in a terminal and get a PID (macOS):

pgrep -n dev-tui2

Track CPU quickly while reproducing:

top -pid "$(pgrep -n dev-tui2)"

Capture profiles (macOS)

Capture both an “idle” and a “streaming” profile so hotspots are not conflated:

sample "$(pgrep -n dev-tui2)" 1 -file /tmp/tui2.idle.sample.txt
sample "$(pgrep -n dev-tui2)" 1 -file /tmp/tui2.streaming.sample.txt

For the streaming sample, trigger a response that emits many deltas (e.g. “Tell me a story”) so the stream runs long enough to sample.

Quick hotspot extraction

These rg patterns keep the investigation grounded in the data:

# Buffer diff hot path (idle)
rg -n "custom_terminal::diff_buffers|diff_buffers" /tmp/tui2.*.sample.txt | head -n 80

# Transcript rendering hot path (streaming)
rg -n "App::render_transcript_cells|Line::render|render_spans|styled_graphemes|GraphemeCursor::next_boundary" /tmp/tui2.*.sample.txt | head -n 120

Rasterization-cache validation checklist

After implementing a transcript rasterization cache, re-run the same scenarios and confirm:

  • Streaming sample shifts away from unicode_segmentation::grapheme::GraphemeCursor::next_boundary stacks dominating the main thread.
  • CPU during streaming drops materially vs baseline for the same streaming load.
  • Idle CPU does not regress (redraw gating changes can mask rendering improvements; always measure both idle and streaming).

Notes to record per run

  • Terminal size: width Ă— height
  • Scenario: idle vs streaming (prompt + approximate response length)
  • CPU snapshot: top (directional)
  • Profile excerpt: 20–50 relevant lines for the dominant stacks

Hanzo Dev pointers

  • hanzo-dev/tui2/src/transcript_view_cache.rs: wrapped transcript memoization + per-line rasterization cache (cached Cell rows).
  • hanzo-dev/tui2/src/transcript_render.rs: incremental helper used by the wrapped-line cache (append_wrapped_transcript_cell).
  • hanzo-dev/tui2/src/app.rs: wiring in App::render_transcript_cells (uses cached rows instead of calling Line::render_ref every frame).