To porovnani xz a zstd me zajima. Vytvarim samospustitelne archivy u kterych mi zalezi hlavne na rychlosti dekomprimace a kompresnim pomeru. Rychlost komprimace neni zas az tak dulezita (ale i zde plati cim rychlejsi, tim samozrejme lepsi). Zde mi vychazeli do ted nejlip kompresni algoritmi typu LZMA: Pomala komprimace, rychla dekomprimace a slusny kompresni pomer.
Zkusil jsem tedy vymenit xz za zstd. Vstupni adresar ma velikost 345.4MB a jedna se o data vseho mozneho druhu, vcetne binarnich (soucasti je dokonce i ISO soubor). Meril jsem beh celeho skriptu, ve vypisu vsak uvadim jen radek s archivatory, protoze maji naprosto zasadni vliv na rychlost provedeni skriptu, nedelal jsem tedy zadny propracovany benchmark, jen jsem chtel videt jak by si oba zpusoby staly v praxi.
Koprimace :
'tar -cvf - . | xz -9 -c - > ../${PRODUCT}' -> 1m 48s -> 251.2MB
'tar -cvf - . | zstd -19 - > ../${PRODUCT}' -> 1m 44s -> 258.2MB
to neni zadny zazrak.
Decomprimace:
'tail -n+$ARCHIVE $0 | tar --xz -xC $GAME_ROOT' -> 0m 14s
'tail -n+$ARCHIVE $0 | tar --zstd -xC $GAME_ROOT' -> 0m 02s
Toz to je ovsem jina pisnicka.
Tak ted jsem docela na vazkach.... Co se tyce dekomprimace, je zstd naprosto bezkonkurencni. Rozdil v rychlosti extraxce byl poznat i bez mereni. Oproti xz opravdu bleskovy. Zas na druhou stranu, na (myslim, ze ) srovnatelnem kompresnim levlu vychazelo xz lepe...
16. 9. 2021, 10:46 editováno autorem komentáře
Pro rychlost komprese se hodí u xz i u zstd parameter -T0
, který použije všechna vlákna procesoru. I když říkáte, že na rychlosti komprese nezáleží.
Zstd má ještě větší a pomalejší kompresi --ultra -22
.
Zstd má navíc v minulém díle zmiňovaný long-mode --long
, což pomůže pro data redundantní s velkým odstupem. Tady bude záležet na vašich datech. Pokud to pomůže, je možné ještě zvětšit třeba --long=28
. Bez čísla je to 27. Víc jak 27 má tu nevýhodu, že to musíte také specifikovat při rozbalování.
Argument -T0 opravdu prinesl jiste zrychleni. u xz se zkratila komprimace zhruba o 20s u zstd jednou tolik.
Argumenty --ultra -22 se v mem pripade projevily uz jen v radu kilobajtu, doba komprimace byla citelne delsi (pres 2 min, i s -T0).
Long-mod je u me asi nepouzitelny. Proces skonci na nedostatek pameti.
Nicmene, budu v pokusech dal pokracovat - uvazuji o tom, ze buildovaci skript, asi bude zjistovat velikost vstupniho adresare a pro velke (dejme tomu > 300MB ) se bude pouzivat zstd, protoze zde uz bude asi vic prevzovat rychlost dekomprimace nad komprimacnim pomerem. V opacnem pripade bude mozna lepsi pouzit xz.
Kadopadne, diky za zajimave clanky i za rady. Rozsahla pojednani o kompresnich algoritmech a jejich srovnani (a obzvlaste v cestine) je dost malo.
PS. Data jsou hodne ruznoroda a po kazde trochu jina. Zatim se jedna o dosove hry zabalene v self-executable archivu...
16. 9. 2021, 12:30 editováno autorem komentáře
xz i zstd i gzip mají dekompresi poměrně rychlou, xz tedy o něco pomalejší, ale pořád výrazně rychlejší než bzip2, který je postavený na úplně jiném typu algoritmu. Proto se bzip2 prakticky přestal používat - je výrazně pomalejší na kompresi než většina ostatních (s výjimkou xz), kompresní poměr je mezi gzip a xz, ale dekomprese je výrazně pomalejší a navíc myslím, že i paměťově náročná.
Prakticky každý moderní kompresor zrychlí lineárně s růstem CPU jader (ne threads, protože ty se budou bít o zdroje, takže přinesou obvykle jen mírný nárust). Důvod, proč xz v tomhle testu zrychlilo jen o 20 s místo o polovinu, je nejspíš omezená velikost bloku - xz aplikuje paralelní kompresi na výrazně větším bloku než ostatní algoritmy, mám pocit, že pro -9 je to půl nebo dokonce jeden GB. Takže 350MB bude v závislosti na kompresní úrovni pro paralelizaci příliš málo, větší smysl bude mít na několika GB datech.
V každém případě, pokud nejde o runtime resource (jako jar, Quake zip apod), tak je to celkem asi jedno - u 14s vs 2s bych řešil víc kompresní poměr než 12s rozdíl ;-) . Zstd funguje dobře na textových datech (JSON jde klidně na 5%), na binárních bude lepší xz, ale v zásadě na binárních (či hůř už zkomprimovaných) nefunguje příliš dobře nic. Spíš bych zkomprimoval každý relevantní podadresář zvlášť, a hodil do jednoho zip, když bude potřeba, protože podle use-case předpokládám, že se vždycky "pracuje" jen s jedním podadresářem.
PS: Benchmarků je plný internet: https://linuxreviews.org/Comparison_of_Compression_Algorithms
[kvr kvr]
Dekuji za doplneni.
Jedna se opravdu o runtime zalezitost - samospustitelne komprimovane archivy, ktere obsahuji data hry, spoustec, ktery obsluhuje dosbox, a dekompresor, ktery pripravy "pudu" pro spusteni hry pro konkretniho uzivatele. Vysledkem je potom jeden nativni spustitelny soubor, obstaravajici vse potrebne, vcetne zalohovani zmenenych dat pomoci overlayfs. Viz. mala ukazka
Vím, že je to v praxi k ničemu, ale jak si vedou takové ty různé PAQ8, ZPAQ a podobně? Nechcete napsat článek i na téma těhle extrémních metod, nebo to alespoň zmínit?
16. 9. 2021, 13:07 editováno autorem komentáře
PAQ a z něj vycházející ZPAQ používají PPM a artitmetické kódování, které jsem zmiňoval v tomto díle. PPM také používá RAR a v některých metodách 7-Zip.
ZPAQ má výbornou kompresi, trvá však dlouho a stejně nebo ještě o trochu déle trvá dekomprese. ZPAQ používá jako extrémní kompresi lrzip -z
(zmiňováno v předchozím díle). Jinak nevím o tom, že by se někde ZPAQ uplatňoval.
Na Silesia Corpusu trvá nejlepší komprese zpaq -m5
480,1 sekund, výsledek má jen 38 931 kB, ale rozbalení trvá 518,6 sekund. Přitom komprese i rozbalení používá 8 vláken.