#tac #reverse #simd #utilities #core #coreutils

app tac-k

按相反顺序打印文件中的行

9 个版本

0.3.3 2024年5月31日
0.3.2 2024年5月30日
0.2.1 2024年5月25日
0.1.3 2024年5月23日

命令行工具 中排名第 1286

MIT/Apache

35KB
351 行(不包括注释)

Tack

Crates.io Version docs.rs Crates.io License Crates.io MSRV

Tack 是 tac 仓库的一个分支。它作为独立的二进制文件 tac-k 和作为库 tac-k-lib 提供。

Tack 是一个高性能、SIMD 加速、跨平台的 GNU Coreutils 中的 tac 工具的重写版本,采用 MIT/Apache-2.0 许可证发布。该工具从文件(或从 stdin,但 见下文)读取输入,然后逐行反向打印。

tac 实现使用 SIMD 加速进行新行检测,并在所有支持的操作系统上使用内存映射文件。此外,它还用 rust 编写,以确保最大程度的完整性和安全性。

谁需要更快的 tac 呢?

好问题。尝试按时间顺序反向搜索多吉字节大小的网络访问日志文件(tac --line-buffered access.log | grep foo),然后告诉我。

用法

Usage: tac [OPTIONS] [FILE]...

Arguments:
  [FILE]...  Files to be reversed.
             Read from stdin if it is `-` or not specified.

Options:
  -s, --separator <BYTE>  Use BYTE as the separator instead of newline.
                          Only single-byte character is supported.
      --line-buffered     Always flush output after each line
  -h, --help              Print help
  -V, --version           Print version

Tack 从任何组合的 stdin 和/或零个或多个文件中读取行,并将行按相反顺序写入输出。

示例

$ echo -e "hello\nworld" | tac
world
hello

$ echo -e "hello\nworld" | tac --separator=o
rld
wohello%

安装

可以通过 cargo,Rust 软件包管理器构建和安装 tack 二进制文件

cargo install tac-k --locked

或者通过 cargo-binstall 使用预构建的二进制文件进行安装

cargo binstall tac-k --locked

可以通过以下方式将 tack 库添加到您的项目中

cargo add tac-k-lib

实现说明

tac 实现使用 SIMD 指令集(AVX2、NEON)来加速新行的检测(如果可用)。内存映射文件的使用还通过避免由于 speculative execution 缓解措施导致的上下文切换引起的降速,从而提高性能。与 GNU Coreutils 中的 tac 版本相比,它显著(如果缓解措施被禁用,则速度快 2.55 倍,否则更快)且具有更宽松的许可。

为了获得最佳性能

  • 尽量不要将输入管道输入到 tac 中。例如,不要运行 cat /usr/share/dict/words | tac,而是直接运行 tac /usr/share/dict/words。因为根据定义,tac 必须到达文件末尾才能以反转行的方式输出其输入,如果您使用 tacstdin 接口(例如 cat foo | tac),它必须在开始处理结果之前缓冲所有 stdin 输入。 tac 将尝试在内存中缓冲,但一旦超过某个高水位线(目前为 4 MiB),它将切换到基于磁盘的缓冲(因为它不知道输入有多大或是否会最终超出可用的空闲内存)。
  • 在可能的情况下,始终尝试将 tac 放置在管道的 开始。即使您可以保证 tac 的输入不会超出内存缓冲区限制(见上文),tac 几乎肯定比您的管道中的任何其他命令都要快,如果您打算反转输出,您将受益最大,如果始终运行命令到完成,则反之亦然。例如,不要运行 grep foo /var/log/nginx/access.log | tac,而是运行 tac /var/log/nginx/access.log | grep foo。这将(显著)减少在报告第一个 n 个匹配之前所需的时间/工作(因为文件首先被快速反转,然后按所需顺序搜索,而不是缓慢地搜索整个文件,然后才反转结果)。
  • 如果 tac 是将输出管道输入到另一个命令而不是直接写入到 tty,请使用行缓冲输出模式(tac --line-buffered)。这为您提供了“实时”结果流,并且如果您只查找前 n 个匹配项,则可以提前终止。例如,tac --line-buffered access.log | grep foo 将比 tac access.log | grep foo 更快地打印其第一个匹配项。
  • 同样,如果您正在链式输出 n 个实用程序的输出,请确保从 n - 1 开始的所有命令都使用行缓冲模式,除非您不关心延迟,只关心吞吐量。例如,为了打印某些 grep 模式的第一个两个匹配项:tac --line-buffered access.log | grep --line-buffered foo | head -n2

许可证

Tack 既可以许可为 MIT,也可以许可为 Apache-2.0,由您选择。

除非您明确声明,否则,根据 Apache-2.0 许可证定义的,您有意提交的任何旨在包含在此软件包中的贡献,应按上述方式双重许可,不附加任何额外条款或条件。

贡献

作为一个开源项目,Tack 的存在离不开其各种贡献者的不懈努力 - 请参阅 CONTRIBUTORS.md 以获取详细信息。

依赖

~1.5MB
~22K SLoC