Puis-je paralléliser le tri?

13

Par exemple, bzipil existe pbzip , une version parallèle de bzip. Existe-t-il de tels outils de parallélisation pour sortaméliorer les performances?

miku
la source

Réponses:

12

Depuis coreutils 8.6 (15/10/2010), GNU sorttrie 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 pigzou pbzip2améliorer gzipou bzip2.

Si votre sortn'est pas parallèle, vous pouvez essayer d'installer le GNU à sortpartir de la dernière version de GNU coreutils .

Avec le tri GNU, vous pouvez limiter le nombre de threads avec l' --paralleloption.

Stéphane Chazelas
la source
2
sort --stable donne une augmentation des performances de 15%, au moins dans ma charge de travail de test.
jrw32982 prend en charge Monica
8

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
benroth
la source
4
Merci, c'est une astuce que j'utilise récemment aussi - laissez simplement trier utiliser la moitié de la RAM, si nécessaire:sort -S 50%
miku
6

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 sortprogramme lui-même échange des morceaux sur le disque et vice-versa. Les sortimplé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é.

sorta une -moption 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.

Warren Young
la source
Merci pour votre réponse. Je conduirai avec des points de repère splitet mergevoir si ça aide.
miku
@miku: Je ne vois pas que cela merge(1)soit applicable ici. Utilisez sort -m.
Warren Young
1
désolé pour mon laxisme, je voulais dire sort --merge.
miku
1
Si vous divisez le fichier et triez les morceaux, vous devrez toujours trier le tout lorsque vous le remonterez, n'est-ce pas? Comment cela sera-t-il plus rapide?
terdon
2
Il s'agit d'une variante de l' algorithme de tri par fusion , l'une des méthodes de tri les plus rapides disponibles.
Warren Young
3

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/shmpour traiter les fichiers intermédiaires.

Saullo GP Castro
la source
3
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 (!!!)

mt_
la source
Merci, mais ça ne suffirait pas LC_ALL=C?
miku
Je pense que oui ... c'est peut LC_COLLATE- être déjà assez. AFAIK sortutilise strcollpour la comparaison et la page de manuel indique que le comportement dépend deLC_COLLATE
mt_
0
#! /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

amicos
la source
1
Salut! Cette réponse pourrait être améliorée en expliquant ce qu'elle est censée faire, plutôt que d'être uniquement un vidage de code (également, si elle a été comparée pour être plus rapide que le tri GNU sur certaines entrées, ce serait intéressant de savoir!).
dhag