Let the numbers speak▊

git startup 3–7x vs Git Bash prompt git segment 4–12x 8/8 ahead on Windows 27x lighter · zero DLLs

Every number carries an artifact or PR anchor (noted row by row); claims we haven't measured don't get printed on this page.

Startup · latency · size

Metricniubash / rubashBaselineRatioSource
git startup (git --version) 13.7 ms avg / 11.5 ms min · git status 22.6 ms Git Bash 45–103 ms (same rig in niu-git#12: mingw64\bin 51.3 ms · cmd\git.exe 45.3 ms) 3–7x faster niu-git#12 (merged 2026-10-16) · niubash#374
One-shot niu -c true 26.3 ms Git Bash 71 ms 2.7x faster GITBASH-KILLER card 6
Prompt git segment reads .git/HEAD ≤29 ms spawns git per prompt, 113–362 ms 4–12x faster GITBASH-KILLER card 3 (real repo, min-of-20)
shell startup (5 measured runs) rubash 27–48 ms Git Bash 60–93 ms · WSL 202–278 ms 2–3x faster data/bench/startup.tsv
Install size niu ≈16 MB · zero DLLs Git Bash 440 MB + 20 MB msys-2.0.dll 27x lighter GITBASH-KILLER card 4 (measured on a real install)
WinuxCmd 3.79 MB carrying 176 commands / 1,924 options · ~19 ms cold start — — WinuxCmd README:32,:74 (PGO: sort −18%, nl −17%)

Same Windows machine: 8/8 faster than Git Bash

2026-10-18 · rubash master 8ab35e89 (incl. #807/#808) · method: Interleaved rounds (rubash → Git Bash → WSL per round), 1 warm-up round discarded, min-of-3, 120 s timeout, identical timing across all three (inner window date +%s%N). Source: data/bench/results.tsv + data/bench/run_bench.sh

Workloadrubash vs Git BashrubashGit Bash
Background wait sleep & wait ×750 1,696 ms 1,967 ms
Background wait ×1500 3,366 ms 3,980 ms
Background wait ×300 694 ms 814 ms
Background wait ×100 263 ms 298 ms
Background subshell ( ) ×750 1,643 ms 2,192 ms
Pure spawn ×750 1,696 ms 2,119 ms
Foreground external command ×750 37 ms 41 ms
Built-in loop ×750 32 ms 40 ms

WSL is a cross-OS reference and meaningless against native Windows, so it is no longer shown in the main table; on native Linux (Android builds included), rubash is also significantly faster than GNU bash on fork/subshell workloads — a dedicated suite will be listed once its artifacts land.

Android baseline (Termux aarch64): measured, honest, post-fix re-run pending niu vs GNU bash 5.3.20 (aarch64) post-fix re-run pending

2026-10-14 · Android tablet · aarch64 · 6 cores · Termux · niu 1.4.0 Android build (embeds rubash e785c3c8f610) vs GNU bash 5.3.20-1 aarch64 (Termux package). Method: same script, interleaved (bash→niu→bash→niu), best-of-3; startup is a median of 20–30 warm runs (wait4 rusage). Source: niubash#352 (full matrix & method) · niubash#349 (the original ~2.1x arithmetic/function datapoint)

Workload (v1.4.0 snapshot)GNU bashniuVerdict
startup niu -c true (median of 30) 8.3 ms 21.1 ms 2.5x slower (+14 ms is the wrapper gap)
arithmetic for loop ×200k 0.572 s 1.353 s 2.37x slower
string expansion ×30k (//, ^^, #, %) 0.325 s 1.198 s 3.69x slower (${x^^} alone up to 7.3x)
pure assignment t=$S ×30k 0.086 s 0.234 s 2.72x slower
peak RSS (VmHWM) 4.6 MB 10.2 MB 2.2x
fib recursion via $( ) ×3000 855.9 s 164.8 s 5.2x faster
subshell/pipeline ×3000 68.0 s 37.9 s 1.8x faster
real script mkdir/write/read-back ×500 9.77 s 4.55 s 2.1x faster

Fork / subshell deep dive rubash engine vs GNU bash 5.3.20 placeholder · pending TSV

2026-10-18 · rubash HEAD 141b460 / niu 1.4.0 · method: Sequential interleaving, min-of-N, per-item timeout guard. Placeholder: figures transcribed from the 2026-10-18 re-run output; promoted once the recheck_fork_20261018-*.tsv artifacts land in data/bench/ (this note is removed after they verify).

Workloadbash → rubashGNU bashrubashniuRatio
$( ) command substitution ×3000 4,382 ms 90 ms 119 ms 48.7x
Backtick substitution ×3000 4,903 ms 79 ms 107 ms 62x
Subshell ( : ) ×5000 5,799 ms 358 ms 382 ms 16.2x
Recursive fib $() ×100 37,300 ms 2,866 ms 3,019 ms 13.0x
External process loop /bin/true ×2000 16,229 ms 16,404 ms 16,478 ms 1.01x
Background sleep & wait ×750 928 ms 2,293 ms 2,423 ms 2.47x

Workloads that also include inline-coreutils gains (listed separately, not counted toward the fork record): Pipeline echo | cat ×2000 190x (17,347→91 ms); Real script mkdir/wc ×250 2.14x (4,123→1,928 ms).

Engineering numbers before → after, each with a PR anchor

ItemNumberSource
One-shot execution optimization (xgr series of six) niu -c true 105.6 ms → 19.8 ms niubash PR #267–#272
Multi-line paste accidental auto-executions 186 → 0; 257-line payload 300 s timeout → 4.6 s PR #252/#288 · paste_multiline_bench.py
nvm.sh re-lex checkpoint gap vs GNU 720x → 8x, re-lexed bytes −40% rubash PR #486
Array element writes O(n²)→O(1) amortized K=5000 single write vs GNU: associative 445x → 9.9x, indexed 736x → 3.8x (the old build was 45x / 177x vs itself); also fixes the O(n²) tokenizer (10,001-segment parse 563→17.8 ms) rubash#618/#616 (ledger: docs/performance.md) · earlier #650/#652
Single spawn cost rubash 1.183 ms vs GNU 1.121 ms — on par (the real exec floor) data/bench/unix-spawn-cost-20261012.md (min-of-3)
Windows hidden-console allocation console-less sessions used to pay ~22 ms per child process → now one allocation per command tree (a windowless console pre-allocated on Win11 24H2+, or adopted from the first CREATE_NO_WINDOW child on older builds); pinned by 14 regression tests rubash#913 (merged 2026-10-20) · design in niubash#462
$(tput …) terminal queries answered in-process the 64-call tput ticket probe fell 1165 ms → 47 ms (~25x, zero spawns, byte-equal to GNU ncurses); the winuxcmd-side twin removed ~17 ms/call of i18n overhead → ~0.4 ms (3,208-row replay byte-identical) rubash#884 · WinuxCmd#1269(均 merged)
[[ ]] direct numeric leaf + decimal fast path 50k [[ 1 -eq 2 ]] 1.41x → 1.10x vs GNU rubash#966(merged 2026-10-21)
Multi-word literal command fast path [ 1 -eq 2 ] ×20k ≈177 → 155 ms rubash#967(merged 2026-10-21)
Whitelist-skip of the procsub metadata scan 1.56x → 1.39x (~11%) rubash#974(merged 2026-10-21)
Decimal-subscript array write fast lane interleaved 8k 3.65x → 3.16x; also fixes a real double side-effect in a[$((i++))]=v rubash#959(merged 2026-10-21)
case: render $BASH_COMMAND head-only 20-arm ×10k −10%, plus a real divergence fix rubash#958(merged 2026-10-21)
export/unset fast-lane family single-probe mirror + bulk unmark; the residual ~100x face stays open (shown as-is) rubash#917/#918/#920 + #943 正确性返工(均 merged)· #916 开放
Silent-builtin short-circuit returns directly on empty output with no redirects; shift ~1.5–4% (still ~2x bash — the bottleneck is elsewhere); export/unset counts unchanged rubash#984 (merged 2026-10-22) · landed in 0aeffe99
Associative-subscript fast lane plain-$name subscript fast lane, interleaved 8k 3.5x → 2.6x (linear, ~3.1x asymptote) rubash#985 (merged 2026-10-22) · landed in 0aeffe99
export/unset IFS-marking skip quoteless words skip identity IFS marking, export/unset 2k 2.14x → 1.97x (~3–4%) rubash#986 (merged 2026-10-22) · landed in 0aeffe99
Compound-literal linearization subscript-span scan O(n²) → linear, 8k fill ~850ms → ~200ms, 20k ~5.1s → 640ms (~8x) rubash#987 (merged 2026-10-22) · landed in 0aeffe99
[ $VAR -op N ] integer fast-expand (pending) loop-while 30k ~2.4x → ~1.8x vs bash; merge pending, not counted in the main table yet rubash#990 (OPEN, pending)

Methodology & sources