1 个不稳定版本
0.1.0 | 2021年8月2日 |
---|
#407 在 Unix API
68KB
2K SLoC
fls
一个接近POSIX兼容且无需libc的 ls
,比GNU的更小、更快、更美观。
exa 和 lsd 都是优秀的 ls
类似Rust程序,但它们的速度比系统 ls
慢,且代码大小大约是其10倍。此外,您实际上不能用它们中的任何一个替换 ls
,因为某些软件依赖于解析 ls
的输出。但即使作为用户体验的改进,我认为其他项目讲述了一个错误的故事;现代软件不需要更大或更慢。
1我并不是要批评GNU的 ls
,但据我所知,它是我在所重视的指标上最接近的东西。
粗略基准测试
--color=never -R / > /dev/null | --color=always -R / | --color=auto ~ | --color=auto -l ~ | |
---|---|---|---|---|
fls |
0.66 秒 | 2.32 秒 | 0.16 毫秒 | 0.30 毫秒 |
GNU ls |
1.22 秒 | 4.37 秒 | 0.38 毫秒 | 2.30 毫秒 |
exa |
3.61 秒 | 63.7 秒 3 | 0.78 毫秒 | 3.30 毫秒 4 |
lsd |
???2 | ???2 | 36.5 毫秒 | 36.8 毫秒 |
这些并不涵盖所有合理的选项组合,但如果您找到了一个组合,其中 fls
比任何替代方案都慢,请提出一个问题。
2lsd
无法检测符号链接循环,因此在 -R /
上会无限运行。
3我有一些大型模糊测试语料库的目录;从我收集这些数据时运行的 perf top
,我看到 exa
大部分时间都花在 term_grid::Grid::column_widths
上。我怀疑它的网格布局算法是二次的。
4我报告的所有情况都是墙时间;这是唯一一个CPU时间有显著差异的情况。 exa
的CPU时间是 ~2.2 倍这个值。
"无需libc"
fls
不链接到任何内容。经过(去除)的 fls
可执行文件比 GNU 的(去除)的 ls
可执行文件小,尽管一些驱动 GNU 的代码位于另一个文件中。
更小且更快?
对代码大小的最大影响是 #![no_std]
,因为标准库的运行时相对较大。标准库的大部分单个组件大小都很合理,但生成回溯的代码非常大,据我所知,#![no_std]
是唯一去除它的方法。其余的代码大小主要通过运行出色的工具 cargo bloat
来缩减,该工具用于识别替换泛型以运行时调度的位置,并通过手动审查代码来提取重复的代码模式。
在速度方面,fls
可能比 GNU 的 ls
更快,因为它不使用 POSIX 接口来列出文件。我们直接调用 getdents64
并解析输出,而不是玩弄 read_dir
的调用。由于我们调用 getdents64
,我们可以访问可选的目录条目类型信息,这通常让我们省去许多 stat
调用,这些调用相对于其他文件系统系统调用可能很昂贵。我说“可能”,因为 fls
总是比 GNU 的 ls
更快。原始目标是直接使用 getdents64
(见下文),一旦我有了可工作的原型,它就比竞争者更快。
--颜色=auto
fls
对 --color=always
和 --color=never
与 GNU ls 具有相同的解释,但在 --color=auto
下,fls
将仅根据文件扩展名和从 getdents64
可用的信息应用颜色,这是可选的。因此,fls --color=auto
的颜色是不可预测的,但你可以在不进行任何昂贵的 stat
调用的同时得到一些输出颜色。fls
是在我开发环境是一个计算节点和 HPC 文件系统时开发的,而在大型目录中使用 ls --color=always
可能需要几秒钟到几分钟。而 fls --color=auto
在那些目录中提供了相同的颜色,只需一眨眼的时间。因此,如果没有提供参数且标准输出是终端,则默认使用 --color=auto
。
排序
在没有选项的情况下,fls
使用类似于 ls -v
的比较函数对名称进行排序,该函数尝试将数字序列视为单个数字。您不需要在文件名中填充数字到固定宽度,以便它们按直观顺序显示。
POSIX 功能
- -A 不要列出隐含的
.
和..
- -C 按列列出列表条目
- -F 在条目后附加指示符
- -H 当在命令行上提供时跟随符号链接
- -L 总是跟随符号链接
- -R 递归到子目录中
- -S 按大小排序
- -a 不要忽略以点(.)开头的条目
- -c 按ctime排序
- -d 列出目录本身,而不是其内容
- -f 不排序
- -g 长格式但无所有者
- -i 打印每个条目的inode
- -k 假设块大小为1024字节
- -l 长格式
- -m 单行,由逗号(,)分隔
- -n 长格式但列出uid和gid而不是名称
- -o 长格式但无组
- -p 在目录后附加指示符
- -q 将不可打印的字符替换为问号(?)
- -r 反向排序顺序
- -s 打印每个文件的块大小
- -t 按修改时间排序
- -u 按访问时间排序
- -x 按行排序条目
- -1 每行列出一条条目
依赖关系
~2MB
~40K SLoC