UNIXsorting命令如何sorting非常大的文件?
UNIX sort
命令可以像这样sorting非常大的文件:
sort large_file
sortingalgorithm是如何实现的?
怎么不会造成内存的过度消耗?
UNIXsorting命令的algorithm细节说,Unixsorting使用外部R-Way合并sortingalgorithm。 链接进入更多的细节,但实质上它把input分成更小的部分(适合内存),然后合并每个部分在一起。
sort
命令将工作数据存储在临时磁盘文件中(通常位于/tmp
)。
警告:这个脚本每个块启动一个shell,对于真正的大文件,这可能是数百个。
这是我为此写的一个脚本。 在4处理器的机器上,它的分类性能提高了100%!
#! /bin/ksh MAX_LINES_PER_CHUNK=1000000 ORIGINAL_FILE=$1 SORTED_FILE=$2 CHUNK_FILE_PREFIX=$ORIGINAL_FILE.split. SORTED_CHUNK_FILES=$CHUNK_FILE_PREFIX*.sorted usage () { echo Parallel sort echo usage: psort file1 file2 echo Sorts text file file1 and stores the output in file2 echo Note: file1 will be split in chunks up to $MAX_LINES_PER_CHUNK lines echo and each chunk will be sorted in parallel } # test if we have two arguments on the command line if [ $# != 2 ] then usage exit fi #Cleanup any lefover files rm -f $SORTED_CHUNK_FILES > /dev/null rm -f $CHUNK_FILE_PREFIX* > /dev/null rm -f $SORTED_FILE #Splitting $ORIGINAL_FILE into chunks ... split -l $MAX_LINES_PER_CHUNK $ORIGINAL_FILE $CHUNK_FILE_PREFIX for file in $CHUNK_FILE_PREFIX* do sort $file > $file.sorted & done wait #Merging chunks to $SORTED_FILE ... sort -m $SORTED_CHUNK_FILES > $SORTED_FILE #Cleanup any lefover files rm -f $SORTED_CHUNK_FILES > /dev/null rm -f $CHUNK_FILE_PREFIX* > /dev/null
另请参阅:“ 使用shell脚本快速sorting大文件 ”
#!/bin/bash usage () { echo Parallel sort echo usage: psort file1 file2 echo Sorts text file file1 and stores the output in file2 } # test if we have two arguments on the command line if [ $# != 2 ] then usage exit fi pv $1 | parallel --pipe --files sort -S512M | parallel -Xj1 sort -S1024M -m {} ';' rm {} > $2
我对这个程序并不熟悉,但是我猜这是通过外部sorting完成的(大部分的问题都是临时文件,而问题的一小部分却一次存储在内存中)。 见Donald Knuth的计算机程序devise艺术卷。 3sorting和检索,5.4节进行深入的讨论。
仔细查看sorting选项以加速性能,并了解它对您的机器和问题的影响。 Ubuntu上的关键参数是
- 临时文件的位置-T directory_name
- 要使用的内存数量-SN%(所有内存的N%越多越好,但是避免过度订购导致交换到磁盘,可以像“-S 80%”一样使用它来使用80%的可用内存,或2GB RAM的“-S 2G”)。
提问者问“为什么不使用高内存?” 答案来自历史,旧的Unix机器很小,默认的内存大小设置很小。 调整这个尽可能大的工作量,以大大提高分类性能。 将工作目录设置在最快的设备上,有足够的空间容纳至less1.25 *的文件大小。
内存不应该是一个问题 – sorting已经照顾到这一点。 如果你想要最佳的使用你的多核CPU,我已经在一个小脚本中实现了这个function(类似于你可能在网上find的一些脚本,但是比大多数脚本更简单/更清洁)。
#!/bin/bash # Usage: psort filename <chunksize> <threads> # In this example a the file largefile is split into chunks of 20 MB. # The part are sorted in 4 simultaneous threads before getting merged. # # psort largefile.txt 20m 4 # # by hp split -b $2 $1 $1.part suffix=sorttemp.`date +%s` nthreads=$3 i=0 for fname in `ls *$1.part*` do let i++ sort $fname > $fname.$suffix & mres=$(($i % $nthreads)) test "$mres" -eq 0 && wait done wait sort -m *.$suffix rm $1.part*