Skip to content

Bind autosuggest widgets once per shell and add CI - #8

Merged
arturict merged 2 commits into
mainfrom
perf/prompt-latency-ci
Oct 5, 2026
Merged

arturict merged 2 commits into
mainfrom
perf/prompt-latency-ci

Conversation

@arturict

@arturict arturict commented Oct 5, 2026

Copy link
Copy Markdown
Owner

Problem

After #7 the shell starts in about 0.15 s, but every prompt still paid about 60 ms before it was drawn. zprof inside a 50,000-file git repository shows _zsh_autosuggest_bind_widgets as the largest cost per prompt: zsh-autosuggestions re-wraps all ~200 ZLE widgets in a precmd hook before every prompt. The repository also had no CI, so #7 was merged on local checks only.

Changes

  • Set ZSH_AUTOSUGGEST_MANUAL_REBIND=1, the option the plugin documents for this cost. The plugin then binds its widgets once, at the first prompt, after all plugins and the theme have defined theirs.
  • Add a GitHub Actions workflow: Bash and PowerShell syntax checks, plus a fresh setup.sh --yes install and a second run as an update in an ubuntu:24.04 container. The installer exits non-zero when one of its checks fails, including the Cut interactive zsh startup from 2.4 s to 0.17 s #7 checks for the duplicate Oh My Zsh load and lazy nvm.

Measurements

Ubuntu 24.04 containers on x1, each a fresh setup.sh --yes install with p10k's lean config and a synthetic git repository with 50,000 committed files (one modified, one untracked). Variants interleaved over four rounds, load 3–6, no capped. "main ohne Doppel-Laden" is main before #7 with the duplicate Oh My Zsh load removed by hand.

Metric main before #7 main before #7, no duplicate load #7 + this PR
zsh -i -c exit, warm (n = 40) 2125 ms 554 ms 153 ms (−93 %)
zsh -i -c exit, cold¹ (n = 20) 2604 ms 1736 ms 1123 ms (−57 %)
zsh -l -i -c exit, warm (n = 20) 2782 ms 1160 ms 143 ms (−95 %)
Time to first prompt (pty) 42.5 ms 72.2 ms 9.2 ms
Time until a typed-ahead command runs 2105 ms 1245 ms 220 ms (−90 %)
Prompt latency per command, 50k-file repo 121 ms 145 ms 39 ms (−68 %)
compinit per start (zprof, median) 1296 ms (3 calls) 39 ms (2 calls) 33 ms (1 call)

This PR on its own, A/B in the same container (#7 vs #7 + manual rebind, 5 sessions × 6 prompts): prompt latency 96 → 35 ms (−64 %), time until a typed-ahead command runs 217 → 191 ms.

¹ Cold = zcompdump, p10k and setup caches deleted before each run; page cache warm.

Verification

  • Widget table (zle -lL, bindkey) after three prompts compared with and without manual rebind: identical except nine widgets p10k wraps at its first prompt (clear-screen, send-break, overwrite-mode, deactivate-region, vi-replace, visual-mode, visual-line-mode, two z4h-*). There the p10k wrapper now sits outside the autosuggest wrapper instead of inside; both call through to the original widget.
  • Interactive pty tests on the branch image, all pass: autosuggestion appears for a history entry, Up arrow runs history-substring-search, Tab completes uv pip ins, nvm ls-rem (zsh-completions) and git chec, alias gst works. On main before Cut interactive zsh startup from 2.4 s to 0.17 s #7, Up arrow and git completion fail because the second Oh My Zsh load rebinds them.
  • Installer: fresh install passes all 68 checks (74 s).
  • PowerShell proxy from Cut interactive zsh startup from 2.4 s to 0.17 s #7, pwsh 7.6 on Linux with real gh, uv and uvx: profile start 1256 → 768 ms (−39 %, n = 20). Not measured on Windows.

Rollout

Ubuntu/WSL: devhub update. Windows: irm https://raw.githubusercontent.com/arturict/zsh-setup/main/setup.ps1 | iex.

Model/harness: Claude Opus 5.5 in Claude Code (T3 Code).

🤖 Generated with Claude Code

arturict and others added 2 commits October 5, 2026 15:50
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@arturict
arturict merged commit cdd560d into main Oct 5, 2026
2 checks passed
@arturict
arturict deleted the perf/prompt-latency-ci branch October 5, 2026 15:53
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