如何加快 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 |