Per verificare come l’efficienza di compressione di un file dipenda dal contenuto creiamo 3 file:
- un file di 1GB di dati casuali (
rando.txt
): - un file di 1GB con la stringa
pippo
ripetuta (pippo.txt
): - un file di 1GB con la stringa
pippo-pluto
ripetuta (pippo-pluto.txt
):
head -c 1G </dev/urandom >rando.txt
yes 'pippo' | tr -d '\n' | head -c 1G > pippo.txt
yes 'pippo-pluto' | tr -d '\n' | head -c 1G > pippo-pluto.txt
Inizialmente, questi tre i file occupano esattamente 1GB:
1 2 3 4 5 |
$ du -b *.txt | sort -h 1073741824 pippo-pluto.txt 1073741824 pippo.txt 1073741824 rando.txt |
Possiamo ispezionare i primi bite di ciascun file in formato esadecimale:
1 2 3 4 5 6 7 8 9 |
$ xxd -l12 pippo.txt 00000000: 7069 7070 6f70 6970 706f 7069 pippopippopi $ xxd -l12 pippo-pluto.txt 00000000: 7069 7070 6f2d 706c 7574 6f70 pippo-plutop $ xxd -l12 rando.txt 00000000: 426d d5d7 a561 4c47 9705 1049 Bm...aLG...I |
Per comprimerli basta usare i seguenti comandi:
1 2 3 4 |
$ gzip -c pippo.txt > pippo.txt.gz $ gzip -c pippo-pluto.txt > pippo-pluto.txt.gz $ gzip -c rando.txt > rando.txt.gz |
oppure usando GNU parallel si possono lanciare i tre processi in parallelo:
1 2 |
$ parallel -v "gzip -c {} > {}.gz" ::: pippo.txt pippo-pluto.txt rando.txt |
I tre file compressi hanno dimensioni diverse: pippo.txt.gz
e pippo-pluto.txt.gz
occupano rispettivamente solamente 1.5MB e 2.0MB, mentre rando.txt.gz
è aumentato di dimensione e occupa 1.1GB:
1 2 3 4 5 |
$ du -b *.txt.gz | sort -h 1562435 pippo.txt.gz 2082672 pippo-pluto.txt.gz 1073915355 rando.txt.gz |
il fatto che comprimendo file con contenuto casuale sia possibile ottenere file di dimensione superiore all’originel è un fenomeno noto.
Un altro esempio: file ordinati e non ordinati
EDIT: 05 marzo 2021
Con lo script generate.sh
è possibile generare due file da 1.0GB, sorted.txt
e unsorted.txt
, composti da due seguenze di parole (nell’esempio pippo
e pluto
).
1 2 |
./generate.sh pluto pippo |
sorted.txt
contiene, in ordine alfabetico, prima una parola e dopo l’altra. In questo caso, la parola pippo
è ripetuta 107374182 volte e così la parola pluto
. Ecco i primi byte del file:
1 2 3 4 5 6 7 8 9 |
$ xxd -l100 sorted.txt 00000000: 7069 7070 6f70 6970 706f 7069 7070 6f70 pippopippopippop 00000010: 6970 706f 7069 7070 6f70 6970 706f 7069 ippopippopippopi 00000020: 7070 6f70 6970 706f 7069 7070 6f70 6970 ppopippopippopip 00000030: 706f 7069 7070 6f70 6970 706f 7069 7070 popippopippopipp 00000040: 6f70 6970 706f 7069 7070 6f70 6970 706f opippopippopippo 00000050: 7069 7070 6f70 6970 706f 7069 7070 6f70 pippopippopippop 00000060: 6970 706f ippo |
unsorted.txt
contiene contiene le stesse parole[1]Questo il conteggio: $ parallel -k -v "grep -oE {2} {1} | wc -l" ::: sorted.txt unsorted.txt ::: pippo pluto
grep -oE pippo sorted.txt | wc -l
107374182
grep -oE pluto sorted.txt | wc … Continue reading in ordine causuale:
1 2 3 4 5 6 7 8 9 |
$ xxd -l100 unsorted.txt 00000000: 706c 7574 6f70 6c75 746f 7069 7070 6f70 plutoplutopippop 00000010: 6c75 746f 7069 7070 6f70 6970 706f 706c lutopippopippopl 00000020: 7574 6f70 6970 706f 7069 7070 6f70 6c75 utopippopippoplu 00000030: 746f 7069 7070 6f70 6970 706f 706c 7574 topippopippoplut 00000040: 6f70 6970 706f 7069 7070 6f70 6970 706f opippopippopippo 00000050: 706c 7574 6f70 6970 706f 706c 7574 6f70 plutopippoplutop 00000060: 6970 706f ippo |
Comprimiamo poi i due file:
1 2 3 4 |
$ parallel -v "gzip -c {} > {}.gz" ::: sorted.txt unsorted.txt gzip -c sorted.txt > sorted.txt.gz gzip -c unsorted.txt > unsorted.txt.gz |
Come previsto, il file ordinato viene compresso a una dimensione molto infieriore rispetto a quello disordinato:
1 2 3 4 |
$ du -b *.txt.gz | sort -h 1562441 sorted.txt.gz 49577747 unsorted.txt.gz |
L’immagine in evidenza è “gzthermal: pseudo-visualization of gzip compression efficiency” di Scott Schiller via Flickr. Rilasciata con licenza CC-BY-NC 2.0.
References
↑1 | Questo il conteggio: $ parallel -k -v "grep -oE {2} {1} | wc -l" ::: sorted.txt unsorted.txt ::: pippo pluto |
---|