bat 本机实测:6.7MB JS 开语法高亮要 12.4s,cat 只要 1.2ms;关颜色约慢 24 倍

上一篇写完 fd 之后预告过,这次实测 sharkdp/bat(读星数约 6.1 万,2026-11-05)。

日常看源码,很多人还在 cat foo.py 或直接丢进编辑器。cat 快、无脑,但没有行号、没有语法高亮、看不见制表符和行尾空格;less 能翻页,高亮要自己配。bat 宣传自己是「带语法高亮和 Git 集成的 cat」。听起来美好,可高亮不是免费的------大文件上到底慢多少、管道场景会不会把装饰全关掉、Debian 上命令到底叫 bat 还是 batcat,我在本机跟 GNU cat 正面比了一轮。

本机实测 + AI 辅助整理。测量时间:2026-11-05(Asia/Shanghai)。每组先预热 1 次,再取中位数(中等文件 7 次、大文件 5 次),输出丢到 /dev/null,文件都在页缓存里,属于「热缓存」成绩。需要语法高亮时显式加 --color=always(因为管道//dev/null 不是 TTY,bat 默认会关颜色,否则测到的只是「关掉高亮的 bat」)。


本机环境

text 复制代码
OS:    Debian 13 x86_64,8 核
bat:   0.26.1(GitHub release 二进制,979ba22)
cat:   GNU coreutils 9.7
less:  未安装(后面分页相关坑会用到)

安装又踩了和 fd 那篇一样的 apt 坑。本机当天:

text 复制代码
$ sudo apt-get install -y bat
E: Unable to locate package bat

官方 README 写得很清楚:Debian/Ubuntu 用 apt 装时,可执行文件经常叫 batcat (跟另一个叫 bat 的包撞名),需要自己 ln -s /usr/bin/batcat ~/.local/bin/bat 或 alias bat=batcat。本机 apt 源直接找不到包,batcat 命令也不存在,于是改走官方 release:

bash 复制代码
curl -sL -o bat.tar.gz \
  https://github.com/sharkdp/bat/releases/download/v0.26.1/bat-v0.26.1-x86_64-unknown-linux-gnu.tar.gz
tar xzf bat.tar.gz
mkdir -p ~/.local/bin
cp bat-v0.26.1-x86_64-unknown-linux-gnu/bat ~/.local/bin/bat
# 若你装的是 apt 包,通常是:
#   sudo apt install bat
#   ln -s /usr/bin/batcat ~/.local/bin/bat

macOS 一般是 brew install bat。下文统一写 bat。

测试素材

复用 ripgrep / fd 那套 corpus,并额外拼了两个大文件:

文件 大小 行数 用途
typing.py(Python 标准库) 130 KB 3819 中等源码,看启动与高亮
large_concat.py(多个 .py 拼接) 2.96 MB 84019 大文本吞吐
large_js.js(playwright 两个 bundle 拼接) 6.67 MB 164119 更大、语法更「重」的 JS

实测 1:中等源码------高亮一开,从 0.6ms 到 123ms

文件:typing.py(130KB)。TERM=xterm-256color。

命令 中位数 相对 cat
cat 0.60 ms 1×
bat --paging=never --color=never 4.05 ms ≈6.8×
bat --paging=never --color=always 123 ms ≈205×
bat --paging=never --color=always --style=plain 121 ms ≈201×
bat --paging=never --color=always -n 129 ms ≈215×
bat --paging=never --color=always --style=full 122 ms ≈203×

结论先说清楚 :日常「打开看一眼」的体感,bat 的高亮开销在百毫秒量级,人眼几乎无感;但别拿它跟 cat 比吞吐------cat 这条路径几乎只做读和写,bat 还要做语法解析和 ANSI 着色。关颜色后大约慢 7 倍,已经能接受;真正贵的是 --color=always。

输出体积也能侧面说明高亮在干什么(同一文件 132718 字节):

模式 输出字节 含 ANSI
cat / bat --color=never 132718 否
bat --color=always --style=plain 620018 是
bat --color=always -n 726950 是
bat --color=always(默认装饰) 831010 是
bat --color=always -A 1573300 是

高亮后体积大约变成原来的 4.7~6.3 倍 ;再加 --show-all 接近 12 倍。终端要画的东西变多了,耗时跟着上去并不意外。

实测 2:2.96MB 拼接源码------关颜色 16ms,开高亮 2.4s

命令 中位数 相对 cat
cat 0.94 ms 1×
bat --paging=never --color=never 16.3 ms ≈17×
bat --paging=never --color=always 2400 ms ≈2540×
bat --paging=never --color=always --style=plain 2359 ms ≈2496×
bat --paging=never --color=always -n 2395 ms ≈2534×

关颜色时 bat 大约慢一个数量级出头;一开高亮直接到 2.4 秒 。-n(行号)在关颜色时有明显额外成本(上一组无 --color=always 的测量里,同文件 bat -n 中位数约 48ms,对关颜色的 16ms),但高亮本身已经贵到把行号开销淹没了。

实测 3:6.67MB JS------开高亮 12.4s,这才是标题里的数字

命令 中位数 相对 cat
cat 1.21 ms 1×
bat --paging=never --color=never 28.4 ms ≈24×
bat --paging=never --color=always 12.42 s ≈10278×

同一台机器、同一份热缓存文件:cat 1.2 毫秒,bat 开语法高亮要 十二秒 。这不是黑 bat------它本来就不是为「把几兆 JS 刷到 /dev/null」设计的------而是提醒:别把 bat 当高速 cat 用在脚本流水线里 ;脚本里需要纯文本透传,用 cat,或至少 bat -pp --color=never。

可复现命令(本机路径请自行替换):

bash 复制代码
# 预热
cat large_js.js >/dev/null
# 关颜色(接近「当 cat 用」)
for i in 1 2 3 4 5; do
  TIMEFORMAT='%R'; time bat --paging=never --color=never large_js.js >/dev/null
done
# 开高亮(会明显变慢)
for i in 1 2 3 4 5; do
  TIMEFORMAT='%R'; time bat --paging=never --color=always large_js.js >/dev/null
done

实测 4:分页、管道、-n / --style=plain / -A

默认管道会「卸妆」

把 stdout 接到管道时,bat 自动关掉颜色,输出字节数与原文件完全一致:

text 复制代码
$ bat typing.py | wc -c
132718          # 和文件本身一样,无 ANSI
$ bat --color=always typing.py | wc -c
831010          # 强制保留高亮

这是特性,不是 bug:避免把 \x1b[38;5;... 灌进 grep/wc/重定向文件。代价是------你在脚本里 bat foo \| something 时,看不到高亮;需要颜色时加 --color=always 或 -f(--force-colorization)。

分页:本机没有 less

bat 默认分页器是 less。本机 which less 直接失败(包都没装)。非 TTY / 管道场景下,bat 多数时候会直接把内容打出来,不硬报错;指定 --pager=less 时也可能静默退化。交互终端里若缺少 less,体验会怪------官方也支持 --pager=builtin(内置 minus)或自己指定 more。

日常建议:

bash 复制代码
# 只想当「更好看的 cat」,永不进分页
alias bat='bat --paging=never'
# 或单次
bat -pp README.md          # -pp = --style=plain --paging=never

-n / --style=plain / -A 的有意义差异

在小样例上(hello\tworld + 行尾空格 + NUL):

text 复制代码
$ printf 'hello\tworld\nline2  \n\0binary?\n' > tabs_sample.txt

$ bat --paging=never tabs_sample.txt
# 制表符、行尾空格、NUL 都「原样」------肉眼几乎看不出问题

$ bat --paging=never -A tabs_sample.txt
hello├─┤world␊
line2··␊
␀binary?␊

-A / --show-all 把 Tab、换行、NUL 变成可见符号,查「明明没字符怎么对不齐」时非常有用。--style=plain(-p)去掉网格/表头等装饰,只留内容(和高亮,若颜色开着);-n 加行号,输出会多出一截前缀(本机 typing.py 关颜色时从 132718 → 151813 字节)。


踩坑清单(都在本机碰到过)

坑 1:Debian/Ubuntu 可能是 batcat,本机 apt 还直接找不到包

text 复制代码
$ sudo apt-get install -y bat
E: Unable to locate package bat

$ batcat --version
bash: line 1: batcat: command not found

官方说明:apt 装上之后命令经常是 batcat ,因为和另一个 bat 撞名。本机连包都定位不到,最终用的是 GitHub release 二进制。换机器时先 which bat batcat,再决定要不要 ln -s。

坑 2:管道自动关颜色------测速时容易「测错对象」

第一次我把 stdout 接到 /dev/null 就开跑,bat 中位数只有约 2ms(中等文件),心里还想「也就慢一点」。加上 --color=always 之后直接跳到 123ms 。原因写在 --help 里:automatic 模式只在交互终端启颜色。对比高亮成本,必须显式 --color=always,否则你测到的是「卸妆版 bat」。

坑 3:默认分页器是 less,系统没装时行为很「软」

text 复制代码
$ which less
# 无输出,退出码 1

$ bat --paging=always --pager=less short.py | wc -c
# 不报错,仍可能打出内容(本机管道场景下拿到了文件原文长度)

不要假设「没 less 就会失败」。CI 镜像、精简容器里很常见。需要稳定分页用 --pager=builtin,不需要分页就 --paging=never。

坑 4:未知主题只警告,不失败

text 复制代码
$ bat --theme=NoSuchThemeXYZ --color=always short.py >/tmp/out 2>/tmp/err
$ echo $?
0
$ cat /tmp/err
[bat warning]: Unknown theme 'NoSuchThemeXYZ', using default.

主题名写错不会非零退出,脚本里检测失败要抓 stderr 或先 --list-themes。本机主题列表一共 28 个。

坑 5:大 JS/大源码开高亮会到秒级

6.67MB 的 JS bundle,--color=always 中位数 12.42s 。不是机器卡死,是语法高亮在干活。预览巨文件、做吞吐脚本,请关颜色或改回 cat。


顺手好用的几个参数

bash 复制代码
bat -n file.py                 # 行号
bat -A file.py                 # 显示 Tab/换行/NUL
bat -pp file.py                # plain + 不分页(很像彩色 cat)
bat --color=always -f          # 管道里也强制颜色和装饰
bat --list-themes              # 看主题
bat --theme=TwoDark file.rs    # 换主题
bat -l python dump.txt         # 强制按某语言高亮

小结

项 本机结果
130KB typing.py cat 0.60ms;bat 关颜色 4.05ms;开高亮 123ms
2.96MB 拼接 py cat 0.94ms;关颜色 16ms;开高亮 2.4s
6.67MB JS cat 1.2ms;关颜色 28ms;开高亮 12.4s
管道默认 自动关 ANSI,输出字节 = 原文件
-A Tab/换行/NUL 变可见符号,查隐形字符有用
坑 batcat 包名、测速忘开 --color=always、less 缺失、未知主题只警告、大文件高亮秒级

一句话:bat 的价值在「人看源码」------行号、高亮、露出身形的空白符;它的成本也在高亮。 当 cat 的替身跑脚本、刷几兆产物到管道里,请关颜色或直接用 cat。它和 ripgrep、fd 是同一作者路线的「友好默认」:交互体验加分,默认真相要自己测。

完整测量日志在本机 bat/measurements.txt;整理版以后会放到 Gumroad,先关注专栏「GitHub实测笔记」。

上一篇:fd 本机实测(/usr 找 *.so,find 72ms / fd 46ms)。

下一篇预告:sharkdp/hyperfine------前面几篇都在手写「预热 + 中位数」,下一篇换成作者同门的基准测试工具,看它怎么处理预热、导出和异常值,并回头复测 bat 这组数字。有问题评论区见,看到都会回。

相关推荐
徐小夕4 小时前
下载量超 30 万的开源智能体 Prime Agent:它把自己从 TypeScript 重写成了 Rust
前端·vue.js·github
miofly7 小时前
GitHub 日榜趋势速报 | 2026-11-05
开源·github
wflynn16 小时前
GitHub 日榜趋势速报 | 2026-11-03
开源·github
u13013016 小时前
GitHub 热榜项目:日榜(2026-11-03)
人工智能·github
GoGeekBaird1 天前
别再给每个 AI 做自我介绍了:我做了一个「个人上下文」管理系统
后端·github·agent
莫晓燚1 天前
Ansible 13 个常用模块---企业实战
git·github
程序员柒叔1 天前
Diagram Design 解构:45 种图型如何用语义路由与 SVG 质量门交付
人工智能·github·agent·skills
逛逛GitHub1 天前
9 个神级 GitHub 项目助你蹭上抖音、小红书 Vibe 知识大赏热点。
github
m4Rk_1 天前
【论文阅读】Agent 记忆机制(119):EvoLife——让具身 Agent 把主动问到的答案沉淀为可复用的空间经验
论文阅读·人工智能·学习·开源·github