web-dev-qa-db-ja.com

UNIXのsortコマンドは、非常に大きなファイルをどのようにソートできますか?

UNIX sortコマンドは、次のように非常に大きなファイルをソートできます。

sort large_file

ソートアルゴリズムはどのように実装されていますか?

なぜメモリの過剰な消費を引き起こさないのですか?

96
yjfuk

NIX Sortコマンドのアルゴリズムの詳細 は、Unix Sortが外部R-Wayマージソートアルゴリズムを使用することを示します。リンクはより詳細になりますが、本質的には入力を小さな部分(メモリに収まる部分)に分割し、最後に各部分をマージします。

106
Matthew

sortコマンドは、作業データを一時ディスクファイル(通常は/tmp)。

42
grawity

警告:このスクリプトは、チャンクごとに1つのシェルを起動します。非常に大きなファイルの場合、これは数百になります。


これは、この目的のために書いたスクリプトです。 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

参照: " シェルスクリプトを使用した大きなファイルの高速ソート "

13
Adrian

私はこのプログラムに精通していませんが、外部ソートによって行われていると思います(問題の大部分は一時ファイルに保持され、問題の比較的小さな部分は一度にメモリに保持されます)。 Donald Knuth's The Art of Computer Programming、Vol。 3主題の非常に詳細な議論については、ソートと検索、セクション5.4

11
pico
#!/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
11
Sergio

ソートのオプションを注意深く見て、パフォーマンスを高速化し、マシンと問題への影響を理解してください。 Ubuntuの主要なパラメーターは次のとおりです。

  • 一時ファイルの場所-T directory_name
  • 使用するメモリの量-SN%(使用するすべてのメモリのN%の方が良いですが、ディスクへのスワップを引き起こすオーバーサブスクリプションは避けてください。「-S 80%」のように使用して、利用可能なRAMの80%または、2 GB RAMの場合は「-S 2G」)

質問者は「なぜ高いメモリ使用量がないのですか?」と尋ねます。その答えは歴史から来ています。古いUNIXマシンは小さく、デフォルトのメモリサイズは小さく設定されています。これをワークロードに対してできるだけ大きく調整して、ソートパフォーマンスを大幅に改善します。作業ディレクトリを、ソートされるファイルのサイズの少なくとも1.25 *を保持するのに十分なスペースがある最速のデバイス上の場所に設定します。

5
Fred Gannett