UNIX sort
komutu çok büyük bir dosyayı şöyle sıralayabilir:
sort large_file
Sıralama algoritması nasıl uygulanır?
Neden aşırı hafıza tüketimine neden olmuyor?
UNIX sort
komutu çok büyük bir dosyayı şöyle sıralayabilir:
sort large_file
Sıralama algoritması nasıl uygulanır?
Neden aşırı hafıza tüketimine neden olmuyor?
Yanıtlar:
UNIX sırala komutunun Algoritmik ayrıntıları Unix sırala Harici R-Way birleştirme sıralama algoritması kullanır diyor. Bağlantı daha fazla ayrıntıya giriyor, ancak özünde girdiyi daha küçük bölümlere (belleğe sığan) böler ve ardından her bölümü sonunda birleştirir.
sort
(Genellikle geçici bir disk dosyalarında verileri çalışma komutu saklar /tmp
).
-T
ile temp
UYARI: Bu komut dosyası yığın başına bir kabuk başlatır, gerçekten büyük dosyalar için bu yüzlerce olabilir.
İşte bu amaçla yazdığım bir senaryo. 4 işlemcili bir makinede sıralama performansını% 100 artırdı!
#! /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
Ayrıca bkz .: " Büyük dosyaları bir kabuk komut dosyasıyla daha hızlı sıralama "
Programa aşina değilim ama sanırım harici sıralama yoluyla yapılıyor (sorunun çoğu geçici dosyalarda tutulurken, sorunun nispeten küçük bir kısmı bir seferde bellekte tutulur). Donald Knuth'un The Art of Computer Programming adlı eserine bakın . 3 Konunun çok derinlemesine tartışılması için Sıralama ve Arama, Bölüm 5.4 .
#!/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
Performansı hızlandırmak için sıralama seçeneklerine dikkatlice bakın ve bunun makineniz ve probleminiz üzerindeki etkisini anlayın. Ubuntu'daki temel parametreler
Soru soran kişi "Neden yüksek bellek kullanımı yok?" Bunun cevabı geçmişten geliyor, eski unix makineleri küçüktü ve varsayılan bellek boyutu küçük ayarlandı. İş yükünüzün sıralama performansını büyük ölçüde iyileştirmesi için bunu mümkün olduğunca büyük ayarlayın. Çalışma dizinini, en hızlı cihazınızda, sıralanan dosyanın en az 1,25 * boyutunu tutacak kadar yeterli alana sahip bir yere ayarlayın.
Hafıza bir sorun olmamalı - sıralama bunu halihazırda halleder. Çok çekirdekli CPU'nuzu en iyi şekilde kullanmak istiyorsanız, bunu küçük bir betikte uyguladım (ağda bulabileceğiniz bazılarına benzer, ancak bunların çoğundan daha basit / daha temiz;)).
#!/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 h.p.
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*