性能特征:哪里快、哪里持平
零 fork 三层模型(见执行模型)的性能含义 可以一句话说清:凡是 bash 要建进程而 niubash 不建的地方,niubash 快; 凡是双方都必须建进程的地方,双方持平。这一页的每个数字都来自同机 实测(方法在文末),基准产物随包附上,可在 基准页 逐条核对。
零 fork 的收益场景
命令替换、子壳、后台作业——bash 语义里每来一次就 fork 一次的构造——在
niubash 里是 ShellState::clone 与 fd 表复制,不经过进程创建。
2026-10-18 同场实测(每轮 ×750 次迭代,交错轮换、弃热身、min-of-3,单位 ms):
| 工作负载 | rubash | Git Bash | WSL(参考) |
|---|---|---|---|
后台子壳 ( ) ×750 | 1643 | 2192 | 123 |
后台等待 sleep & wait ×750 | 1696 | 1967 | 154 |
| 纯 spawn ×750 | 1696 | 2119 | 158 |
| 内建循环 ×750 | 32 | 40 | 3 |
| 前台外部命令 ×750 | 37 | 41 | 857 |
对 Git Bash 是 8 个工作负载全部占优;WSL 列仅作参考——Linux 内核 fork 让它的 后台作业天然占优,但它的前台外部命令要跨 OS 文件边界(857 ms)、冷启动 202–278 ms,且带走一整套虚拟机。迁移评估时,按你的脚本里「fork 密集」还是 「外部命令密集」对号入座。
外部进程:持平是设计事实
niubash 不宣称外部进程更快——因为它不该更快。单次 spawn 成本 rubash
1.183 ms vs GNU 1.121 ms:持平,因为两者最终都落在同一个
Win32 CreateProcess 地板上。零 fork 的全部收益来自「不建进程」
的路径,不来自把「必须建的进程」变快。这也是与 MSYS 层的本质区别:Git Bash
的每个进程还要额外支付 fork 模拟的税。
引擎内热路径:差距是修出来的
语言层的重负载也被逐个啃掉,而不是留着当「已知慢」:nvm.sh 这类重词法脚本的 解析差距从 720 倍压到 8 倍(重词法字节量 −40%);数组元素写入从 O(n²) 改为 O(1) 追加——K=5000 时关联数组单次写快 45 倍、索引数组覆盖写快 177 倍; 多行粘贴的自动误执行从 186 次降到 0(257 行载荷从 300 秒超时降到 4.6 秒)。 这些不是理论优化:每项都有 PR 号与基准脚本可复现,夜间性能门盯住它们不回潮。
启动数字
| 指标 | niubash 系 | 对照 |
|---|---|---|
git 启动(git --version) | ~14 ms(niu-git:MSVC + schannel,无 MSYS) | Git Bash 45–103 ms |
一次性执行 niu -c true | 26.3 ms | Git Bash 71 ms |
| shell 启动(5 次实测) | rubash 27–48 ms | Git Bash 60–93 ms · WSL 202–278 ms |
| 提示符 git 段 | 读 .git/HEAD,≤29 ms | 每条提示符 spawn git 113–362 ms |
| WinuxCmd 工具层 | 3.79 MB 携带 176 命令 / 1,924 选项,~19 ms 冷启 | — |
| 安装体积 | niu ≈16 MB · 零 DLL | Git Bash 440 MB + 20 MB msys-2.0.dll |
提示符一项值得展开:Git Bash 兼容主题不 spawn git 子进程,而是直接读
.git/HEAD 文件(微秒级),把「每敲一条命令付一次 git 启动」变成
「不付」。一次性执行数字对 agent 与 CI 尤其重要——niu -c 的
冷启动地板从 105.6 ms 一路压到 26.3 ms(一次性快路径六连 PR)。
怎么读这些数字
环境:Intel Xeon w5-3435 · Windows 10 19045 · 同机 WSL2 Ubuntu(GNU Bash 5.3.0 对照)· Git Bash 5.3.0。方法:交错轮换(rubash→Git Bash→WSL)、弃 1 轮热身、min-of-3、三方同一计时法。数字随版本会动,口径不变:未实测不写、 输赢都展示。仓库另有夜间性能门(每资产计时趋势,超预算硬失败)防止回潮。
完整表、原始 TSV 与运行脚本见 /benchmarks/。