mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-04 02:21:47 +00:00
perf(tui): full-pipeline instrumentation + profiling harness
Extends HERMES_DEV_PERF to capture the complete render pipeline, not
just React commits. Adds scripts/profile-tui.py to drive repeatable
hold-PageUp stress tests against a real long session.
perfPane.tsx:
Wires ink's onFrame callback (already plumbed through the fork) into
the same perf.log as the React.Profiler samples. Captures per-phase
timing (yoga calculateLayout, renderNodeToOutput, screen diff, patch
optimize, stdout write) plus yoga counters (visited/measured/cache-
Hits/live) and patch counts per frame. Events are tagged
{src: 'react'|'frame'} so jq can split them. logFrameEvent is
undefined when HERMES_DEV_PERF is unset, so ink doesn't even attach
the callback.
entry.tsx:
Passes logFrameEvent into render().
types/hermes-ink.d.ts:
Declares FrameEvent + onFrame on RenderOptions so the ui-tui side
type-checks against the plumbed-through ink option.
scripts/profile-tui.py:
New harness. Launches the built TUI under a PTY with the longest
session in state.db resumed, holds PageUp/PageDown/etc at a
configurable Hz for N seconds, then parses perf.log and prints
per-phase p50/p95/p99/max plus yoga-counter summaries. Zero deps
beyond stdlib. Exit 2 if nothing was captured (wiring broken).
Initial findings (1106-msg session, 6s PageUp hold at 30Hz):
- Steady state: 10 fps; renderer phase p99=63ms, write p99=0.2ms
- 4/107 heavy frames (>=16ms), all dominated by renderNodeToOutput
- One pathological 97ms frame with yoga measuring 70,415 text cells
and Yoga visiting 225k nodes — the cold-unmeasured-region hit
- Ink's scroll fast-path (DECSTBM blit from prevScreen) is
disqualified because our spacer-based virtual history doesn't
keep heightDelta in sync with scroll.delta, so every PageUp step
falls through to a full 2000-4800 patch re-render instead of ~40
This commit is contained in:
parent
69ff201050
commit
71eee26640
4 changed files with 461 additions and 30 deletions
|
|
@ -41,6 +41,10 @@ if (process.env.HERMES_HEAPDUMP_ON_START === '1') {
|
|||
|
||||
process.on('beforeExit', () => stopMemoryMonitor())
|
||||
|
||||
const [{ render }, { App }] = await Promise.all([import('@hermes/ink'), import('./app.js')])
|
||||
const [{ render }, { App }, { logFrameEvent }] = await Promise.all([
|
||||
import('@hermes/ink'),
|
||||
import('./app.js'),
|
||||
import('./lib/perfPane.js')
|
||||
])
|
||||
|
||||
render(<App gw={gw} />, { exitOnCtrlC: false })
|
||||
render(<App gw={gw} />, { exitOnCtrlC: false, onFrame: logFrameEvent })
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue