Kompresja danych

W tym artykule zajmujemy się niektórymi aspektami związanymi z kompresją danych w Linuksie, będą omówione popularne narzędzia oraz zostanie zaprezentowany niewielki test porównujący wybrane narzędzia. Na początku jednak podjemy podstawow przykładay działania narzędzi do kompresji danych w wierszu poleceń.

Przykład kompresji

Jednym z wciąż popularnych narzędzi jest gzip. Program działa w następujacy sposób: wskazany plik zamienia na plik z rozszerzeniem .gz o zmniejszonej wielkości:

$ ls -l plik1
-rw-rw-r-- 1 libran libran 2000000 Jan 11 18:23 plik1
$ gzip  plik1
$ ls -l plik1.gz 
-rw-rw-r-- 1 libran libran 1002610 Jan 11 18:23 plik1.gz

Widzimy, że rozmiar pliku zmniejszył się z około 2 MB do 1 MB.

Aby odzyskać pierwotny kształt pliku stosujemy dekompresję za pomocą opcji -d

$ gzip  -d plik1.gz 
$ ls -l plik1
-rw-rw-r-- 1 libran libran 2000000 Jan 11 18:23 plik1

Uwagi o kompresji danych.

curl https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.18.3.tar.xz |  xz -d | tar  xvf -   -C /tmp/

Narzędzia do kompresji

7z

7z (7-zip) to program i format kompresji danych. Program p7zip jest przeniesioną z Uniksa wersją archiwizatora plików 7-Zip, pracującą w wierszu poleceń, która obsługuje charakteryzujący się bardzo wysokim współczynnikiem kompresji format 7z.

p7zip zapewnia narzędzia do pakowania i rozpakowywania archiwów 7z działające w powłoce lub z graficznym interfejsem użytkownika (takie jak: Ark, File Roller lub Nautilus).

Format 7z to rodzaj kontenera o otwartej architekturze pozwalającej wewnętrznie stosować różne typy kompresji. Obecnie format opiera się głównie na algorytmach LZMA i LZMA2, ale obsługuję równiej BZIP2, GZIP, ZIP XZ i TAR

brotli

Brotli to algorytm bezstratnej kompresji danych ogólnego przeznaczenia, który pakuje dane używając nowoczesnych wariantów algorytmy LZ77, kodowania Huffmana oraz modelowania kontekstowego. Stopień kompresji jest podobny do najlepszych obecnie dostępnych rozwiązań. Brotli zostało stworzone przez inżynierów pracujących w Google, jako alternatywa dla gzip służąc do pakowania treści przesyłanych przez HTTP w serwerach WWW i CDN. Ze względu na metodę słownikową oraz stosunkowo małe okno dekodera, szczególnie nadaję się do pracy urządzenia o mniejszych możliwościach sprzętowych np. w telefonach komórkowych. brotli może nie być odpowiednio wydajne w przypadku kompresji dużych plików.

bzip2 i pbzip2

bzip2 jest ogólnie dostępnym, wolnym od patentów, kompresorem danych. bzip2 kompresuje pliki przy użyciu sortującego bloki algorytmu kompresji tekstu Burrowsa-Wheelera oraz kodowania Huffmana. Kompresja jest zazwyczaj znacznie lepsza, niż osiągi bardziej konwencjonalnych kompresorów opartych na technikach LZ77/LZ78 i wydajnością zbliżona do statycznych kompresorów z rodziny PPM.

pbzip2 jest zrównolegloną implementacją bzip2 pozwalającą przyspieszyć pracę na procesorach wielordzeniowych. Wykrywa automatycznie liczbę dostępnych rdzeni albo używa liczby wątków podanej jako parametr -p.

compress

compress to szybki, prosty kompresor oparty o algorytm LZW Nie osiąga dużego stopnia kompresji, ale jest jednym z szybszych programów tego typu. Jest też jednym ze starszych programów i przez długi czas traktowany był jako faktyczny standard kompresji w świecie systemów UNIX.

gzip i pigz

gzip i format gz zestaw opracowany jako alternatywa dla compress w związku z problemami patentowymi algorytmu LZW. gzip opiera się na algorytmie Deflate, który jest kombinacją LZ77 i kodowania Huffmana. gzip jest ustandaryzowany w dokumentach RFC. W systemach Linux występuję w postaci biblioteki zlib i jest używany w wielu narzędziach, np. do pakowania archiwów TAR, w formacie obrazów PNG oraz w systemach pakietów oprogramowania.

pigz, to podobnie jak pbzip2, zrównoleglona implementacja narzędzia gzip pozwalająca przyspieszać pracę na maszynach wielordzeniowych.

lrzip

lrzip z założenia ma osiągać duży stopień kompresji i dużą szybkość działania dla dużych plików. Używa w tym celu różnych algorytmów: zpaq i lzma do osiągania dużego stopnia kompresji, lzo dla dużej szybkości oraz dalekozasięgowej redukcji redundancji algorytmu rzip. Całość jest zaprojektowana do skalowania się wraz z dostępną wielkością pamięci operacyjnej RAM. Program pozwala użytkownikowi wybierać algorytmy pakowania w zależności od danych i dostępnych zasobów sprzętowych.

lzma

LZMA to algorytm kompresji słownikowej podobny do LZ77. Charakteryzuje się wysokim stopniem kompresji, dużym użyciem RAM do kompresji i niskim zapotrzebowaniem na RAM do dekompresji, co znajduje zastosowanie w systemach osadzonych. Polecenie lzma jest dostępne w Linuksie jako samoistne narzędzie i format plików, ale też algorytm jest używany przez inne narzędzia

lzop

lzop to implementacja algorytmu LZO, będącego pochodną algorytmów z rodzina Lempel-Ziv (LZ77). Przewidziane jest jako szybszy w działaniu od gzip kosztem nieco gorszego stopnia kompresji, przy niewielkich wymaganiach sprzętowych. Szczególny nacisk położony jest na szybkość dekompresji. Uznawane za jedno z szybszych narzędzi do kompresji.

xz i pixz

xz to udoskonalona implementacja LZMA. Kosztem użycia pamięci operacyjnej oferuje duże stopnie kompresji, porównywalne z bzip2, oraz szybki, prosty mechanizm dekompresji. Nadaje się do kompresji plików tekstowych, kodów źródłowych, danych w plikach tekstowych.

xz jest używany do kompresji pakietów dystrybucyjnych przez Linux kernel, Debian, Ubuntu, Slackware, i inne projekty; wyparł w tej roli bzip2 i gzip.

zip/unzip

Info-ZIP to wolna implementacja obsługi formatu ZIP z DOS-owego programu PKZIP, oparta o algorytm Deflate. ZIP jest de facto standardem pakowania i przenoszenia danych między różnymi systemami. Program Info-ZIP jest uznawany za jeden z najszerzej przeportowanych programów w historii.

zpaq

zpaq to narzędzia i format plików służące do wykonywania przyrostowych kompi zapasowych. Skupia się na obsłudze deduplikacji, szyfrowania i kompresji jedno- i wieloczęściowych archiwów. Stosuje różne poziomy kompresji w zależności od rodzaju danych, włącznie z całkowitym brakiem kompresji w przypadku wykrycia danych losowych (nie poddających się kompresji) w celu optymalizacji szybkości działania.

zstd

zstd (Zstandard) to nastawione na szybkość narzędzie oparte na rodzinie algorytmów LZ77, podobne do gzip i xz. Ofertuje dużą i regulowaną szybkość kompresji oraz wysoką szybkość dekompresji, przy zachowaniu stopnia kompresji porównywalnego z gzip/zip. Narzędzie zostało opracowane przez pracowników Facebooka i wydane w 2016 roku. Format posiada standaryzację w dokumentach RFC. Narzędzie ma też opcjonalną funkcję dalekozasięgowej deduplikacji podobnej do tej w lrzip/rzip

Algorytmy i debiut

Narzędzie Algorytmy Rok publikacji
7z LZMA, LZMA2
brotli LZ77, Huffman, context modeling 2016
bzip2 block sort
compress LZW
gzip deflate -> LZ77, Huffman
lrzip zpaq, LZMA, LZO, rzip
lzop LZO -> LZ77 1996
zip deflate LZ77+Huffman 1989
zpaq różne 2009
zstd LZ77 family + FSE & huff0 2016

Test porównawczy

Wykonajmy poglądowe porównanie narzędzi do pakowania. W tym celu wykonamy spakowanie przykładowego pliku za pomocą każdego narzędzia w jego domyślnej konfiguracji i opcjach. Jako plik testowy posłuży pakiet z projektu http://www.stringology.org/projects/PragueCorpus/. Plik został pobrany z http://www.stringology.org/projects/PragueCorpus/data/corpus_files/PragueCorpus.tar.gz, rozpakowany za pomocą gzip ale pozostawiony jako archiwum tar. Archiwum zawiera 30 plików w 8 kategoriach, m.in. dokumenty, arkusze, pliki dźwiękowe i graficzne, skrypty, kody źródłowe, kody binarne oraz pliki typu markup. Całość w postaci rozpakowanej zajmuje około 60 MB.

Testy wykonano na komputerze o konfiguracji:

Wyniki

Program Czas kompresji Czas dekompresji Stopień kompresji
7z 7.91 1.36 1.92
brotli 145.98 0.31 1.96
bzip2 4.52 1.82 1.94
compress 0.71 0.25 1.30
gzip 2.09 0.32 1.60
lrzip 3.76 0.44 1.81
lzma 15.66 1.54 1.92
lzop 0.08 0.06 1.29
pbzip2 0.80 0.34 1.94
pigz 0.22 0.18 1.60
pixz 5.39 0.63 1.92
xz 17.21 1.53 1.92
zip 2.02 0.36 1.60
zpaq 1.38 0.24 1.49
zstd 0.26 0.05 1.59

[ Tabela 1. ]

Czas kompresji (Mniejsza wartość jest lepsza.)

Ze względu na przejrzystość z wykresu usunięto z niego czas dla broli, który jest ponad 8-krotnie większy od następnego w kolei xz.

Zdecydowanym liderem w kategorii czasu pakowania jest tu lzop, za raz za nim jest pigz i zstd. Najgorzej wypadają 7z, lzma i xz. i oczywiście brotli. Wynik dla brotli (146 s w stosunku do pozostały programów z czasem od 0.08 s do 17.21 s) należy traktować z dystansem. Prawdopodobnie zestaw danych był dla tego programu wybitnie nie optymalny, zabrakło odpowiednich opcji, albo inne warunki spowodowały tak słaby wynik.

Warto zwrócić uwagę na pary narzędzi jedno- i wieloprocesorowych:

Program Czas kompresji Czas dekompresji Stopień kompresji
bzip2 4.52 1.82 1.94
pbzip2 0.80 0.34 1.94
gzip 2.09 0.32 1.60
pigz 0.22 0.18 1.60
xz 17.21 1.53 1.92
pixz 5.39 0.63 1.92

[ Tabela 1a ]

Uzyskujemy tu kilkukrotne przyspieszenie operacji pakowania i rozpakowania, dzięki dostępności równoległej pracy na procesorze wielordzeniowym.

Czas dekompresji (Mniejsza wartość jest lepsza.)

W kategorii czasu rozpakowania najlepiej wypadają zstd, lzop i pigz a najgorzej xz, lzma i bzip2. Na pocieszenie można powiedzieć, że czasy dekompresji są znacznie krótsze niż czasy kompresji dla wszystkich narzędzi.

Stopień kompresji (Większa wartość jest lepsza.)

Największy stopień kompresji uzyskują brotli, pbzip2, bzip2 i xz, najgorszy zpaq, compress i lzop.

Widać wyraźnie trzy grupy programów o zbliżonym stopni kompresji co za pewne wiąże się ze stosowaniem w ramach tych grup podobnych algorytmów.

Uwagi do wyników

Chcąc znaleźć odpowiedź na pytanie który program do kompresji wybrać należałby powtórzyć testy dla szerszej grupy danych testowych. A jeśli wiadomo do czego szczególnie kompresja ma służyć to warto przeprowadzić własne testy na konkretnych danych.

Pakiety Debian/MXLinux użyte w teście:

brotli bzip2 gzip lrzip lzop ncompress p7zip-full pbzip2 pigz pixz xz-utils zip zpaq
zstd

Zobacz także: Brotli - poziomy kompresji

desktop linux polecenia serwer terminal