Czy pliki tarowania mogą poprawić kompresję?

9

Czy tarowanie wielu plików razem może poprawić kompresję za pomocą standardowych narzędzi, np. Gzip, bzip2, xz?

Od dawna myślałem, że tak jest, ale nigdy tego nie testowałem. Jeśli mamy 2 kopie tego samego pliku o wielkości 20 MB losowych bajtów tar, razem, sprytny program do kompresji, który zdaje sobie sprawę, że może skompresować cały plik tarball do prawie 20 MB.

Właśnie próbowałem tego eksperymentu przy użyciu gzip, bzip2 i xz do kompresji 1) pliku losowych bajtów, 2) tarballa dwóch kopii tego pliku i 3) kota dwóch kopii tego pliku. We wszystkich przypadkach kompresja nie zmniejszała rozmiaru pliku. Jest to oczekiwane w przypadku 1, ale w przypadkach 2 i 3 optymalnym rezultatem jest to, że plik 40 Mb może zostać zmniejszony do prawie 20 Mb. To trudny wgląd w program kompresji, szczególnie dlatego, że redundancja jest daleka, więc nie spodziewałbym się idealnego rezultatu, ale nadal myślałem, że będzie kompresja.

Test:

dd if=/dev/urandom of=random1.txt bs=1M count=20
cp random1.txt random2.txt
cat random1.txt random2.txt > random_cat.txt
tar -cf randoms.tar random1.txt random2.txt
gzip -k random* &
bzip2 -k random* &
xz -k random* &
wait
du -sh random*

Wynik:

20+0 records in
20+0 records out
20971520 bytes (21 MB) copied, 1.40937 s, 14.9 MB/s
[1]   Done                    gzip -k random*
[2]-  Done                    bzip2 -k random*
[3]+  Done                    xz -k random*
20M random1.txt
21M random1.txt.bz2
21M random1.txt.gz
21M random1.txt.xz
20M random2.txt
21M random2.txt.bz2
21M random2.txt.gz
21M random2.txt.xz
40M random_cat.txt
41M random_cat.txt.bz2
41M random_cat.txt.gz
41M random_cat.txt.xz
41M randoms.tar
41M randoms.tar.bz2
41M randoms.tar.gz
41M randoms.tar.xz

Czy to jest ogólnie to, czego powinienem się spodziewać?

Czy istnieje sposób na poprawę kompresji?

Prakseolityczny
źródło
Twoje przypadki testowe są złymi przykładami. Spróbuj wykonać test z, powiedzmy, katalogiem ~ 100 (prawdziwych) plików tekstowych.
lcd047,
Dlaczego to zły przykład? Wiemy dokładnie, czego się spodziewać. Losowy plik nie może być skompresowany, a 2 losowy plik można skompresować na pół.
Praxeolitic
Problemem jest „losowa” zawartość pliku. Są nieściśliwe. Użyj dwóch różnych dużych plików tekstowych, aby uzyskać lepszy pomysł. Pokrewną ideą jest tutaj „znormalizowana różnica kompresji”. Możesz zajrzeć na ims.cuhk.edu.hk/~cis/2005.4/01.pdf, aby zobaczyć, jakie problemy możesz napotkać podczas tego rodzaju testów.
Bruce Ediger,

Odpowiedzi:

11

Jesteś przeciwny „rozmiarowi bloku” sprężarki. Większość programów do kompresji dzieli dane wejściowe na bloki i kompresuje każdy blok. Wygląda na to, że rozmiar bloku bzip wzrasta tylko do 900 KB, więc nie zobaczy żadnego wzorca, który powtórzy się dłużej niż 900 KB.

http://www.bzip.org/1.0.3/html/memory-management.html

gzip wydaje się używać bloków 32K.

Z XZ masz jednak szczęście! Ze strony podręcznika:

   Preset   DictSize   CompCPU   CompMem   DecMem
     -0     256 KiB       0        3 MiB    1 MiB
     -1       1 MiB       1        9 MiB    2 MiB
     -2       2 MiB       2       17 MiB    3 MiB
     -3       4 MiB       3       32 MiB    5 MiB
     -4       4 MiB       4       48 MiB    5 MiB
     -5       8 MiB       5       94 MiB    9 MiB
     -6       8 MiB       6       94 MiB    9 MiB
     -7      16 MiB       6      186 MiB   17 MiB
     -8      32 MiB       6      370 MiB   33 MiB
     -9      64 MiB       6      674 MiB   65 MiB

więc „xz -8” znajdzie do 32 MB wzorców, a „xz -9” do 64 MB wzorców. Ale uwaga, ile pamięci RAM wymaga kompresji (i dekompresji) ...

bez danych
źródło
1
Tak, xz -8 nie zmniejsza tarballa i kota w teście do 21M.
Praxeolitic,
1
To coś więcej niż tylko rozmiar bloku. Ale cała historia nie jest czymś, co można wyjaśnić w kilku akapitach dotyczących SE.
lcd047,
1
@Praxeolitic Kurs kompresji danych może pomóc.
lcd047,
1
@ lcd047 Kompresja jest ogromnym tematem, ale pytanie brzmiało po prostu „dlaczego nie kompresował”, a odpowiedź brzmi, ponieważ kompresja działa na powtarzających się wzorach, a wzorzec, który chciał znaleźć, potrzebował więcej czasu, niż by szukało to jakiekolwiek narzędzie.
danych
1
Myślę też, że warto wiedzieć, że „-9” w większości kompresorów wiersza poleceń nie oznacza „trudniej znaleźć wzorce”, oznacza „rozważ większe przestrzenie wzorców”.
danych
2

Losowe zawartości pliku wybrałeś nie jest dobrym przykładem - sprasowane archiwów tar będzie większy niż oryginały. To samo zobaczysz w przypadku plików w już kompresowanych formatach (na przykład wiele formatów obrazu / audio / wideo).

Ale łączenie wielu plików ze ściśliwą zawartością zwykle powoduje mniejszy całkowity rozmiar pliku tar niż w przypadku oddzielnego tarowania, zwłaszcza gdy zawartość jest podobna (na przykład pliki logów z tego samego programu). Powodem jest to, że niektóre dane przesunięcia kompresji dla poszczególnych plików (takie jak tablice wzorców dla niektórych algorytmów kompresji) mogą być współużytkowane przez wszystkie pliki w tym samym pliku tar.

Dan Cornilescu
źródło
@kos Zależy to od zastosowanego algorytmu i danych. Cytowane 33% dotyczy wyjątkowego przypadku. Za pomocą gzip i bzip2 zmierzyłem dla 1000 losowo wygenerowanych plików 1 MB, co oznacza wzrost o <1% na każdy plik.
jofel 20.04.16
2

Jak już wspomniano:

  1. Używanie plików losowych nie jest dobre, ponieważ zawierają one już maksymalną „entropię informacji”, dlatego nie można ich skompresować;
  2. Musisz uczciwie spakować dużo plików.

Lepszym przypadkiem testowym może być:

cd /var/tmp
tar -zcf test1.tar /usr
tar -cf test2.tar /usr
gzip test2.tar
ls -h

(Uwaga: Mam nadzieję, że pod nią nie ma wierzchowców /usr!)

Zamiast tego możesz użyć tar -jcfkompresji xz.

Teraz, jeśli test2.tar.gzjest mniejszy niż test1.tar.gz, to test się powiedzie (tzn. Tarowanie plików, a następnie kompresowanie jest lepsze niż kompresowanie niż tarowanie). Sądzę, że tak będzie w przypadku wielu (tj. Tysięcy) plików. Minusem jest to, że wykonanie go może potrwać dłużej, a także wymaga dużo więcej miejsca na dysku, ponieważ najpierw musi skompilować cały plik tar, a następnie go skompresować. Dlatego zamiast tego często używana jest pierwsza metoda, ponieważ kompresuje ona każdy plik w locie, nawet jeśli nie daje tak małego tarballa.

Na przykład w naszej zewnętrznej kopii zapasowej zwykle tworzymy kopię zapasową 4 000 000 plików o łącznej wielkości około 2 TB. Tak więc pierwsza metoda jest znacznie szybsza i nie wymaga dodatkowych 2 TB dysku.

quazza
źródło
Nie -zkompresuje archiwum (tj. Tar)? Zazwyczaj nazwa pliku wyjściowego z czfkońcówką .tar.gz to podkreśla.
Jari Keinänen