Réponses:
Depuis coreutils 8.6 (15/10/2010), GNU sort
trie déjà en parallèle pour utiliser plusieurs processeurs lorsqu'ils sont disponibles. Donc, il ne peut pas être encore amélioré à cet égard comme pigz
ou pbzip2
améliorer gzip
ou bzip2
.
Si votre sort
n'est pas parallèle, vous pouvez essayer d'installer le GNU à sort
partir de la dernière version de GNU coreutils .
Avec le tri GNU, vous pouvez limiter le nombre de threads avec l' --parallel
option.
La seule chose qui m'aide toujours le plus avec le tri est de lui donner le plus de mémoire possible, afin de réduire les échanges, par exemple:
sort -S 20G
sort -S 50%
Si votre fichier est suffisamment volumineux, le tri entraînera un échange de disque, soit parce que la mémoire virtuelle allouée est trop volumineuse, soit parce que le sort
programme lui-même échange des morceaux sur le disque et vice-versa. Les sort
implémentations plus anciennes sont plus susceptibles d'avoir ce type de comportement de "tri via le tampon de disque", car c'était la seule façon de trier les fichiers volumineux dans le passé.
sort
a une -m
option qui peut vous aider ici. Il pourrait être plus rapide de diviser le fichier en morceaux - par exemple avec split -l
- les trier indépendamment, puis de les fusionner à nouveau.
Là encore, il se peut que c'est exactement ce que fait le "tri via le tampon de disque". La seule façon de savoir si cela aide est de le comparer à votre charge de test particulière. Le paramètre critique sera le nombre de lignes auquel vous donnez split -l
.
split
et merge
voir si ça aide.
merge(1)
soit applicable ici. Utilisez sort -m
.
sort --merge
.
J'ai eu un gain très important en utilisant sort -n
, ce qui nécessite des valeurs numériques (float ou entier) dans toutes les colonnes sélectionnées, sans notation scientifique.
Une autre possibilité qui pourrait apporter une grande amélioration à votre processus est d'utiliser le dossier mappé en mémoire /dev/shm
pour traiter les fichiers intermédiaires.
export LC_COLLATE=C
export LANG=C
cat big_file | sort > /dev/null
Habituellement, le tri Linux fait des trucs astucieux pour se conformer aux règles d'égalité Unicode ... si vous changez les paramètres régionaux en C, il passe en octet uniquement ...
Pour un fichier de 1,4 Go, la différence sur ma machine est de 20 s contre 400 s (!!!)
LC_ALL=C
?
LC_COLLATE
- être déjà assez. AFAIK sort
utilise strcoll
pour la comparaison et la page de manuel indique que le comportement dépend deLC_COLLATE
#! /bin/sh
#config MAX_LINES_PER_CHUNK based on file length
MAX_LINES_PER_CHUNK=1000
ORIGINAL_FILE=inputfile.txt
SORTED_FILE=outputfile.txt
CHUNK_FILE_PREFIX=$ORIGINAL_FILE.split.
SORTED_CHUNK_FILES=$CHUNK_FILE_PREFIX*.sorted
#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 -n -t , -k 1,1 $file > $file.sorted &
done
wait
#echo "**********SORTED CHUNK FILES*********"
#echo $SORTED_CHUNK_FILES
#Merging chunks to $SORTED_FILE ...
sort -mn $SORTED_CHUNK_FILES > $SORTED_FILE
#Cleanup any lefover files
rm -f $SORTED_CHUNK_FILES > /dev/null
rm -f $CHUNK_FILE_PREFIX* > /dev/null
le fichier est divisé et trié, il augmentera la vitesse de tri