
从 hyperfine、httptap 和 tuios 出发,分别练习把一条命令的多次测量、一次 HTTP 请求的五个阶段和一整屏终端的内部结构读出来,并给出今晚能跑通的最小路径。
b33755f,它换掉了默认输出的形状,也移除了几个选项。3 主分支最近一次提交在北京时间 10 月 10 日 00:06。-r/--runs 可以写死。4 输出的均值、标准差与最小/最大值,都来自这一批运行。--setup 在整组测量前跑一次,--warmup 在测量前跑几次,--prepare 在每次测量前跑,--conclude 与 --cleanup 收尾。4 最常见的用法是让 --prepare 每次先清掉文件系统缓存,把冷缓存和热缓存分开测。-S,此时它先单独测一次 shell 的启动耗时,再从每次结果里减掉。--metrics 能选墙钟时间、CPU 时间(用户态与内核态)、内存峰值,以及 CPU 周期、指令数、缓存未命中、分支预测失败这些硬件计数器。4 预设 default 是墙钟时间加内存峰值,time 是四种时间,all 是全部。--export-json 写出 schema v2 的结构:每次运行、每个指标各一条记录,外加按指标分组的统计摘要。1 --export-markdown 与 --export-csv 各给一份能直接贴进报告的表格。
doc/execution-order.png 画的那张执行顺序图,取自 v2.0.0 标签。4.deb 包和 musl 静态包,macOS 用 Homebrew,也可以 cargo install --locked hyperfine,但走 cargo 要 Rust 1.97 以上。4curl -sSL -o hf.tar.gz \
https://github.com/sharkdp/hyperfine/releases/download/v2.0.0/hyperfine-v2.0.0-x86_64-unknown-linux-musl.tar.gz
tar xzf hf.tar.gz
./hyperfine-v2.0.0-x86_64-unknown-linux-musl/hyperfine --versionhyperfine 2.0.0hyperfine --warmup 2 -r 8 'sleep 0.05' 'sleep 0.06'Benchmark 1: sleep 0.05 (8 runs)
mean ± σ min … max
Wall Time 51.0 ms ± 0.0 ms 51.0 ms … 51.1 ms
Memory 3.5 MiB ± 0.0 MiB 3.5 MiB … 3.5 MiB
Benchmark 2: sleep 0.06 (8 runs)
mean ± σ min … max
Wall Time 61.1 ms ± 0.0 ms 61.0 ms … 61.1 ms +19.7%
Memory 3.5 MiB ± 0.0 MiB 3.5 MiB … 3.5 MiB 0.0%python3 -c "pass" 是 36.4 毫秒、峰值 13.2 MiB,python3 -c "import json,re,hashlib" 是 69.2 毫秒、18.7 MiB。hyperfine 'echo hi | wc -l' 原样跑一次。本机报的是 Command 'echo hi | wc -l' contains unquoted shell syntax ('|'),并要求在 -S 与 -N 里选一个;加上 -S 之后它还会提示这条命令不到 5 毫秒、墙钟时间可能测不准。hyperfine --metrics time_wall_clock:ms,memory_peak_resident:MiB,instructions 'sleep 0.02'。本机报 Metric 'instructions' is unavailable for 'sleep 0.02',因为硬件计数器要 perf 权限,而这里 /proc/sys/kernel/perf_event_paranoid 是 3。4--parameter-scan 扫一个参数:hyperfine --parameter-scan num_threads 1 4 'sleep 0.{num_threads}',再看 --export-json 出来的 parameters 字段。4--time-unit、--sort、--reference 三个选项被移除,单位改写进 --metrics;JSON 导出换成 schema v2,读旧文件的脚本要跟着改;Markdown、AsciiDoc 与 org-mode 导出只保留第一个指标;默认不经 shell,依赖管道或重定向的命令要显式加 -S。1 两条限制:启用 shell 时硬件计数器不可用,内存峰值在 Windows 上还没实现。4--resolve。5 0.8.0 补上 --har 导出,0.8.1 的变更记录那一节是空的。8 主分支最近一次提交落在北京时间 10 月 10 日 04:25。httpcore 的 trace hooks 记录下 DNS 解析、TCP 连接、TLS 握手、服务端等待与响应体传输的边界时刻,取不到细粒度数据时退回到估算值。9--slo total=500,ttfb=200 给每个阶段设一个毫秒预算,超了就按退出码 4 结束;-f/--fail 遇到 4xx/5xx 退出 22。这套退出码沿用 BSD sysexits.h 的约定,脚本和 CI 能直接判断。9curl -w、httpstat 与 httpie 在阶段计时、瀑布图、JSON 导出、SLO 检查、TLS 检查上的差别,并写明各自适合的场景。9pip install httptap 一条命令,需要 Python 3.11 到 3.15,除标准网络能力外没有系统依赖。9 不想装进环境的话,uvx --from httptap httptap 或官方容器镜像也行。pip install httptap
httptap https://example.com IP: 172.66.147.243 (IPv4) | HTTP: HTTP/2.0 | Proxy: direct | TLS: TLSv1.3 |
Cipher: TLS_AES_256_GCM_SHA384 | Cert: example.com | Issuer: Cloudflare TLS
Issuing ECC CA 3 | Expires: 73d
Status: 200 | Size: 400 B | Server: cloudflare
Request Timeline:
⠿⠿⠿⠿⠿⠿⠿⠿⠿ DNS: 5.2 ms
⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿ Connect: 5.7 ms
⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿ TLS: 8.8 ms
⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿ Wait: 11.8 ms
⠿⠿⠿⠿⠿⠿⠿⠿ Transfer: 4.9 ms
Total: 36.5ms (1 char ≈ 0.60ms)httptap --metrics-only https://example.com 只输出一行 key=value,方便脚本读。本机拿到的是 Step 1: dns=5.7 connect=5.6 tls=9.8 ttfb=31.5 total=36.5 status=200 bytes=400 ip=104.20.23.154 family=IPv4 tls_version=TLSv1.3 proxy=direct。ttfb 是从请求开始到收到首字节的累计值,等于 DNS、连接、TLS 三段加上等待段。瀑布图上的 Wait 只是其中最靠后的一段,这里是全篇最容易看错的一处。httptap --slo total=1 https://example.com。本机退出码是 4,报告仍然完整渲染,失败的那条阈值和超出多少都列在最后。10httptap --json - https://example.com 把结构化结果打到标准输出,顶层是 schema_version、steps、summary,每个 step 的 timing 里分别给 dns_ms、connect_ms、tls_ms、ttfb_ms、total_ms。-4 或 -6 只走一种地址族,比一比连接时间。9--ignore-ssl 与 --cacert 互斥,前者只该在可信网络里用;代理按 -x/--proxy、NO_PROXY、协议对应环境变量、ALL_PROXY 的顺序生效,而 NO_PROXY 只认主机名,不认网段。9 升级真正有内容的一步是升到 0.7 以上,0.8.0 与 0.8.1 本身只动了导出和打包。8x/net 升到 v0.60.0,修掉 GO-2026-6603 到 GO-2026-6617 一组 net/http、HTTP/2 与 crypto/tls 公告。11 其中 GO-2026-6617 能让客户端借着 HPACK 编码器里的竞争条件把 HTTP/2 服务端搞崩,所以跑 tuios-web 的要先升。11 0.9.0 与 0.9.1 在前一天连着发,主分支最近一次提交在北京时间 10 月 12 日 22:32。12-tags ghostty 换成 libghostty-vt;tuios --version 会告诉你手上这个二进制是哪一个。13tuios status working --app build --progress 40,这样一个构建脚本就和一个编码 Agent 一样出现在侧栏与收件箱里。14go.mod 把工具链钉在 go1.26.9。11curl -sSL -o tuios.tar.gz \
https://github.com/Gaurav-Gosain/tuios/releases/download/v0.9.2/tuios_0.9.2_Linux_x86_64.tar.gz
tar xzf tuios.tar.gz
./tuios --versiontuios version 0.9.2 [pure-Go backend]
Commit: 937cc6935448c36d2a8e8b3282fe1f76afb6cb6e
Built: 2026-10-09T08:11:42ZTERM is not set, so TUIOS cannot tell what the terminal can render.。想先看一眼它长什么样,可以打开 tuios.dev/learn,那是编译成 WebAssembly 的同一份程序,每个窗格里配了一个练习用的 shell。16./tuios --standalone # 不启守护进程,只跑这一次tuios --standalone 跑一次,再不带参数跑一次,对比两者的会话生命周期——后者挂在守护进程上,终端关掉之后窗格还在。15tuios --list-themes 会列出一长串主题(本机从 3024_day、3024_night 开始),tuios --preview-theme dracula 可以先看颜色再决定。15internal/vt/ 目录,从 ANSI 解析器的入口读起;再对着 internal/app/render.go,看一次按键事件怎么走到重画。13tuios status working --app build --progress 40,然后看程序状态文档里还允许报告些什么。14[keybindings] 里多了 keyboard_layout 与 option_glyphs 两个键,默认值保持旧行为;守护进程协议没变,但重连相关的修复在守护进程里,要 tuios kill-server 重启才生效,而这一步会关掉所有会话里的窗格;tuios-web 的静态字体从 TTF 换成 WOFF2,自己页面或代理里引用过 TTF 路径的要改。11 还有一条:kitty 图形协议只在部分终端上画得干净,VS Code 与 Netcatty 这类基于 xterm.js 的终端会留下残影,tuios 现在在那里改用块状字符画图。11| 你想练的主线 | 仓库与本期信号 | 最小条件 | 第一条可观察路径 | 主要限制 |
|---|---|---|---|---|
| 测量方法与统计 | hyperfine · 2.0.0 北京时间 10 月 8 日凌晨发布 | 一个静态二进制 | 同一条命令跑 8 次,读均值与标准差两列 | 硬件计数器要 perf 权限;默认不经 shell。(README) |
| HTTP 协议与延迟定位 | httptap · 0.8.1 北京时间 10 月 10 日凌晨发布 | 一条 pip install,Python 3.11 以上 | 一次请求拆成五段的一条瀑布图 | 只支持 Python 3.11–3.15;代理与证书选项有互斥关系。(README) |
| 终端、PTY 与 TUI 架构 | tuios · v0.9.2 北京时间 10 月 9 日傍晚发布 | 预编译二进制加一个真终端 | --standalone 起一屏,再从 internal/vt/ 读起 | 必须在真终端里跑;纯 Go 与 ghostty 各一个二进制。(架构文档) |
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
docs.httptap.dev
github.com
github.com
github.com
github.com
github.com
tuios.dev
This story was produced automatically by a channel. One sentence is all it takes for Neodrop to keep producing for you.