如何加快 sort 的排序速度

GNU sort 工具是我们经常用来对文本文件进行排序或去重的工具。sort 默认的参数可能并不适合排序上 G 的大文件。我们来看一下经常被忽略的 GNU sort 单文件排序优化策略。

例如,我们有一个 100G 的 data.csv 文件,要按第一列的编号排序。命令如下:

env LC_ALL=C sort -S 60% -k 1n,1n -t, --parallel=4 --compress-program=pzstd -o data_sorted.csv data.csv

其中:

  • env LC_ALL=C 指定 sort 按照字节排序,无视内容的语言和编码。在不同的语言环境下,sort 会根据该语言的特点进行字典序的比较,减慢了运行速度,而我们通常不需要这样的比较。如 zh_CN.UTF-8 下,sort 结果会按汉语拼音排序。如果内容是 UTF-8 编码,因为其编码特性,直接按字节排序会得到和 Unicode 码位顺序相同的结果,所以也不必指定 env LC_ALL=C.UTF-8 之类的环境。 [1]
  • -S 60%,--buffer-size,使用 60% 的内存,也可以指定 8G 这样的内存使用量。
  • -k 1n,1n,--key,使用第一列按数字顺序排序。指定 1n,1n 而不是 1n 是由于 1n 实际上是指第一列到最后一列,1n,1n 才是只考虑第一列。
  • -t,,--field-separator,用逗号分隔。
  • --parallel=4,用四个 CPU 并行。
  • --compress-program=pzstd,用 pzstd 压缩中间结果,以免浪费临时文件写入时间。pzstd 是一个高效的压缩软件,也可以尝试 lz4、lzop、gzip 等较快的压缩工具。

还可以尝试的选项:

  • -T,--temporary-directory 选项也可以使用,将临时目录指定在较快的固态硬盘分区,或避免 /tmp 存不下临时数据。
  • -u,--unique,去除重复行。

若要不排序去除重复行,安装 GNU datamash,使用 datamash rmdup 1;如果没有,则可以利用 awk '!seen[$0]++' (用 mawk 可提高速度)。

[1]http://utf8everywhere.org/zh-cn#facts