`~/.vite-plus/env` costs 85-315 ms per shell start on long PATHs (super-linear `${var#*pattern}` in the dedupe loop)
Maintainer antworten meist innerhalb von 1 Tag
Ein zugehöriger Pull Request wurde bereits gemerged.
- #2905 von @jonatankruszewski — gemerged
Bewertung
- Schwierigkeit
- 2/5
- Geschätzter Aufwand
- 1-3 Stunden
- Anfängerfreundlichkeit
- 82/100
- Issue-Typ
- Bug
- Klarheit
- Klar beschrieben
- Aktivitätsstatus
- Aktiv
- Bereich
- cli, developer-experience, performance, tooling
Rechercherichtung
Das POSIX-Umgebungs-Template ist ENV_TEMPLATE_POSIX in crates/vp_global_cli/src/commands/env/setup.rs. Ersetze die ${__vp_tmp#*":${__vp_dir}:"} Deduplizierungsschleife durch den in der Issue angegebenen IFS-Split-Rebuild, damit PATH auf zsh, bash und dash linear bleibt. Füge die Umschreibung in den vorhandenen Snapshot-Runner aus #2494 (sh, bash, zsh) ein und bestätige, dass die generierte ~/.vite-plus/env weiterhin den gleichen PATH erzeugt.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Summary
The PATH dedupe loop in the POSIX env script (ENV_TEMPLATE_POSIX in crates/vp_global_cli/src/commands/env/setup.rs, introduced by #2494, shipped as ~/.vite-plus/env) runs
__vp_after="${__vp_tmp#*":${__vp_dir}:"}"
once per occurrence of each vp dir in PATH. ${var#*X} (shortest-prefix removal with a leading *) is super-linear in the offset of X on every POSIX shell I tested. With a PATH of ~8 KB (147 entries, which is what mise activate produces for a user with ~110 globally installed tools) each expansion takes 50-260 ms depending on the shell, and the loop runs twice (bin and fallback-bin).
Because the installer puts . "$HOME/.vite-plus/env" into ~/.zshenv, this is paid by every zsh process on the machine, interactive or not: zsh -c true goes from 0 ms to 180 ms. Every #!/usr/bin/env zsh script, every zsh -c from a tool, every IDE env probe pays it.
Environment: vp v1.0.0, macOS 26 arm64, zsh 5.9 (/bin/zsh) and 5.9.2 (brew), bash 5.3.15 and 3.2, dash.
Repro (zsh, 3 lines)
PATH="$(printf '/Users/me/.local/share/mise/installs/tool-%03d/latest/bin:' {1..140})/x/bin"; tmp=":${PATH}:"; d=/x/bin
typeset -F3 SECONDS=0; a="${tmp#*":${d}:"}"; print "#* : ${SECONDS}s"
SECONDS=0; b="${tmp%%":${d}:"*}"; print "%%* : ${SECONDS}s"
#* : 0.109s
%%* : 0.000s
Measurements
Single ${tmp#*":${dir}:"} on an 8.7 KB PATH, target dir last:
| shell | #* (shipped) |
%% |
|---|---|---|
| zsh 5.9 | 147 ms | 5 ms |
| zsh 5.9.2 | 146 ms | 5 ms |
| bash 5.3.15 | 63 ms | 14 ms |
| bash 3.2 | 53 ms | 13 ms |
| dash | 264 ms | 4 ms |
Cost of sourcing the whole env file in zsh -f as PATH grows (vp dirs present, so the loop runs):
| PATH entries | chars | time |
|---|---|---|
| 20 | 1353 | 4 ms |
| 40 | 2653 | 13 ms |
| 80 | 5253 | 51 ms |
| 147 | 9656 | 172 ms |
| 300 | 19754 | 720 ms |
Whole env file from the real 147-entry PATH, median of 5:
| file | zsh 5.9 | zsh 5.9.2 | bash 5.3 | bash 3.2 | dash |
|---|---|---|---|---|---|
shipped ~/.vite-plus/env |
177 | 178 | 85 | 83 | 315 |
| literal-prefix one-liner (see below) | 6 | 6 | 128 | 133 | 147 |
| IFS-split loop (proposed) | 6 | 6 | 9 | 13 | 5 |
Proposed fix
A literal-prefix strip (__vp_after="${__vp_tmp#"${__vp_before}:${__vp_dir}:"}") fixes zsh but makes bash and dash slower (table above). Splitting PATH on : once and rebuilding it is linear on every shell and produced an identical PATH to the current script in /bin/sh, dash, bash 3.2, bash 5.3 and zsh for a PATH containing both vp dirs, one of them twice:
__vp_bin="$HOME/.vite-plus/bin"
__vp_fallback="$HOME/.vite-plus/fallback-bin"
__vp_new=
__vp_ifs=$IFS
IFS=:
if [ -n "${ZSH_VERSION-}" ]; then setopt localoptions shwordsplit noglob; else set -f; fi
for __vp_p in $PATH; do
case "$__vp_p" in "$__vp_bin"|"$__vp_fallback") ;; *) __vp_new="${__vp_new:+${__vp_new}:}${__vp_p}" ;; esac
done
IFS=$__vp_ifs
[ -n "${ZSH_VERSION-}" ] || set +f
PATH="${__vp_bin}${__vp_new:+:${__vp_new}}:${__vp_fallback}"
export PATH
unset __vp_bin __vp_fallback __vp_new __vp_ifs __vp_p
The snapshot runner from #2494 already exercises the file in sh, bash and zsh, so the rewrite can slot into the same tests.
Who hits this
Anyone whose PATH is long when a nested shell starts: mise/asdf/nix users with many tools, monorepo devs with per-package bin dirs, CI images. A fresh login shell with a 30-entry PATH pays ~4 ms, which is why it is easy to miss.
- Vorherrschende Sprache
- Rust
- Sterne
- 6k
- Forks
- 271
- Ø Merge
- 1 T. 14 Std.
- Gemergte PRs (30 T.)
- 183
Entwicklungsumgebung
Startet den Dev-Container des Projekts im Browser, mit Ihrem eigenen GitHub-Konto.
- Kein Dockerfile und keine Docker-Compose-Datei
- Keine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus voidzero-dev/vite-plus
-
PowerShell `vp` wrapper hides failures: `$?` is `True` and `&&` keeps going after `vp` failsEvtl. vergeben Ein verknüpfter Pull Request ist offen oder bereits gemergt. Offenpending triage
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
voidzero-dev/vite-plus#2934 ·
Maintainer antworten meist innerhalb von 1 Tag
-
pending triage
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 74/100
voidzero-dev/vite-plus#2932 ·
Maintainer antworten meist innerhalb von 1 Tag
-
pending triage
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 85/100
voidzero-dev/vite-plus#2892 · 1 Reaktion ·
Maintainer antworten meist innerhalb von 1 Tag
-
pending triage
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
voidzero-dev/vite-plus#2882 · 2 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
-
documentation pending triage
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 78/100
voidzero-dev/vite-plus#2875 · 4 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
Alle Issues in voidzero-dev/vite-plus
Ähnliche Issues
-
mxl-compile: пример заполнения ячеек отклоняется UnicaEvtl. vergeben Ein verknüpfter Pull Request ist offen oder bereits gemergt. Offen
Schwierigkeit 1/5 1-3 Stunden Anfängerfreundlichkeit 91/100
IngvarConsulting/unica#1301 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
-
curator: add tutros/sbxmOffen
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 75/100
ajeetraina/awesome-docker-sbx#220 ·
-
`helios / deploy`: switch zone wait in `deploy.sh` has almost no headroom over healthy startup timesEvtl. vergeben Ein verknüpfter Pull Request ist offen oder bereits gemergt. OffenTest Flake
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 74/100
oxidecomputer/omicron#11453 ·
Maintainer antworten meist innerhalb von 1 Tag