Skip to content

perf(dashboard): consolidate jq calls and buffer render output#17

Open
MuLinForest wants to merge 1 commit into
kayhaowu:mainfrom
MuLinForest:fix/dashboard-render-perf
Open

perf(dashboard): consolidate jq calls and buffer render output#17
MuLinForest wants to merge 1 commit into
kayhaowu:mainfrom
MuLinForest:fix/dashboard-render-perf

Conversation

@MuLinForest
Copy link
Copy Markdown

Summary

Two rendering improvements to dashboard.sh:

1. Consolidate jq calls (11× faster per session)

Replace 10 individual jq invocations per session with a single call using join("\u001f") (ASCII Unit Separator, octal \037).

Benchmark (100 render iterations, 1 session file, Debian/Linux):

Method real time per render
Old: 10 × jq calls 16.9s ~169ms
New: 1 × jq call 1.5s ~15ms

→ 11× faster per session. The bottleneck is process fork overhead — each jq invocation is a fork+exec+read; with n sessions the old code did 10n forks per render.

Using \u001f instead of @tsv (tab) also fixes a correctness bug: with IFS=$'\t' read, consecutive empty fields (e.g. git_branch and last_activity both empty) collapse into one separator, silently shifting all subsequent fields — causing BRANCH to display the mem_kb value instead of the git branch.

_US=$(printf '\037') is used instead of $'\x1f' for POSIX sh / dash compatibility (Debian's /bin/sh is dash, which does not support the $'...' escape syntax).

2. Buffer render output (flicker-free)

Buffer the entire frame in a subshell (_frame=$(...)) and flush it atomically with a single printf '\033[2J\033[H%s'. This eliminates the visible partial-frame flicker caused by incremental line-by-line terminal writes interleaved with the kernel scheduler.

Test plan

  • Run dashboard with 1+ active Claude Code sessions, verify all fields (especially BRANCH) display correctly
  • Verify no visible flicker between render cycles
  • Verify works under sh / dash (not just bash)

Replace 10 individual `jq` invocations per session with a single call
using `join("\u001f")` (ASCII Unit Separator, octal \037). This reduces
process forks from O(10n) to O(n) per render cycle.

Benchmark (100 iterations, 1 session file):
  Old (10 jq calls): 16.9s real  →  ~169ms per render
  New (1 jq call):    1.5s real  →  ~15ms  per render
  → 11× faster per session

Using \u001f instead of @TSV (tab) also fixes a correctness bug: with
`IFS=$'\t' read`, consecutive empty fields (e.g. git_branch and
last_activity both empty) collapse into one separator, silently
shifting all subsequent fields — causing BRANCH to display the mem_kb
value instead. The non-whitespace Unit Separator preserves empty fields
correctly.

Use `_US=$(printf '\037')` instead of `$'\x1f'` for POSIX sh / dash
compatibility (Debian's /bin/sh is dash, which does not support the
`$'...'` escape syntax).

Buffer the entire frame in a subshell (`_frame=$(...)`) and flush it
atomically with a single `printf '\033[2J\033[H%s'`. This eliminates
visible partial-frame flicker caused by incremental line-by-line writes.

Co-Authored-By: MuLinForest <5525477+MuLinForest@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 4.6 <claude-code@mulin.date>
MuLinForest added a commit to MuLinForest/claude-code-toolkit that referenced this pull request Mar 26, 2026
…session_title in single jq call

Resolve dashboard.sh conflict: add session_title to PR kayhaowu#17's consolidated
jq read, removing the redundant individual jq calls from PR kayhaowu#15.

Co-Authored-By: Claude Sonnet 4.6 <claude-code@mulin.date>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant