Aktuelle Komprimierprogramme in der Übersicht

Aus LinuxUser 10/2010

Aktuelle Komprimierprogramme in der Übersicht

© Thoursie, sxc.hu

Zip und Zop

Ob fürs Archiv oder für die Webseite zum Download: Alternativen zu Gzip und Bzip2 sparen noch mehr Platz oder arbeiten schneller.

Fast jeder Linux-Anwender stolpert früher oder später über Dateien mit der Endung .gz und .bz2. Gzip und Bzip2 gehören zu den gängigen Programme, um unter Linux eine einzelne Datei zu komprimieren. Dabei spart Bzip2 in der Regel etwas mehr Platz, braucht dafür aber länger. Es gibt jedoch Alternativen: Die parallelen Bzip-Varianten Pbzip, Lbzip2 sowie Neulinge wie Xz, Lzip, Lzma, Lzop und Exoten wie Kgb, Paq8L, Zp, Zpaq oder Lrzip.

Die verlustfreie Datenkompression basiert darauf, die Informationsdichte zu erhöhen und Wiederholungen zusammenzufassen. Die in diesem Artikel verwendeten Komprimier-Programme verwenden dazu unterschiedliche Algorithmen (siehe Tabelle “Verwendete Kompressionsalgorithmen”).

Verwendete Kompressionsalgorithmen

Programm Algorithmus Multithreading Mehrere Dateien?
7zip primär LZMA, aber auch viele andere Unix-Port p7zip zumindest für LZMA nein ja, einzeln, mit -ms=on zusammen
Gzip Deflate nein nein
Bzip2 Burrows-Wheeler, Move to Front, Huffman nein nein
Pbzip2, lbzip2 wie Bzip2 ja nein
Xz LZMA2, optional andere nein nein
Zip Deflate, optional auch bzip2 und LZMA nein ja, einzeln
Lzip LZMA nein nein
Lrzip LZMA, optional auch LZO und ZPAQ nein ja, mit lrztar
Lzma LZMA nein nein
Rar LZ und PPM nein ja, zusammen
Kgb PAQ6 nein ja, zusammen
Paq8l PAQ8 nein ja, zusammen
Zp ZPAQ, vorkompiliert nein ja, zusamen und einzeln
Zpaq ZPAQ nein ja, zusammen und einzeln

Kurz und prägnant

Ein typischer deutscher Text besteht aus maximal 26 Klein-, 26 Groß-Buchstaben, ein paar Umlauten und ein paar Satzzeichen. Die Zeichenkodierung Latin 1 verwendet für jedes Zeichen ein Byte, also 8 Bit; das neuere UTF-8 bis zu 4 Byte. Eigentlich reichen für 32 oder 64 Zeichen fünf oder sechs Bits. Ein einfaches Komprimier-Programm könnte also ermitteln, wieviele unterschiedliche Byte-Werte eine Datei enthält, und für diese eine neue Kodierungstabelle mit weniger Bits anlegen.

Die Huffmann-Kodierung arbeitet nach diesem Prinzip, geht aber noch einen Schritt weiter und verwendet abhängig von der Häufigkeit eines Zeichens eine unterschiedlich lange Bitfolge [1]. So kodiert sie den häufig vorkommen Buchstaben E zum Beispiel mit der Bitfolge 10 (eins null), während sie für den selteneren Buchstaben Y vielleicht 11010 (eins eins null eins null) verwendet.

Auch Bzip2 verwendet die Huffman-Kodierung. Es bringt die Daten jedoch vorher blockweise in eine Reihenfolge, in der gleiche Symbole häufiger direkt hintereinanderkommen, und sortiert diese häufigen Symbole an den Anfang, damit diese kleinere Werte erhalten[2]. Die blockbasierte Arbeitsweise eignet sich gut für das Aufteilen in Threads.

Wörterbücher

Anders arbeiten Verfahren, die anhand eines Wörterbuches Sequenzen durch kürzere Sequenzen ersetzen. Die Algorithmen der Lempel-Ziv-Familie wie LZ77, Lempel-Ziv-Storer-Szymanski (LZSS), LZ78, Lempel-Ziv-Welch (LZW), Lempel-Ziv-Markow (LZMA) und Lempel-Ziv-Oberhumer (LZO) arbeiten nach diesem Prinzip.

Das älteste dieser Verfahren, LZ77 kodiert zum Beispiel das Wort “PAPAYA” wie folgt: “P” anhängen und weiter, “A” anhängen und weiter, die letzten beiden Buchstaben nochmal und “Y” anhängen, “A” anhängen [3]. Je größer der Bereich für das Suchen nach Wiederholungen desto effizienter arbeitet der Algorithmus. Allerdings wächst damit die Größe des Wörterbuches, was das Auffinden von Einträgen verlangsamt.

Die anderen Varianten modifizieren den Algorithmus, um unter anderem mit größeren Wörterbüchern höhere Informationsdichten zu erzielen – bis auf LZO, das auf hohe Geschwindigkeiten beim Packen und vor allem beim Entpacken optimiert ist. Die Verfahren LZ78 und das im GIF-Bildformat verwendete LZW waren bis zum Jahre 2004 in einigen Ländern patentiert und kamen daher in freier Software selten zum Einsatz.

Besonders effizient arbeitet das neuere LZMA, das Wahrscheinlichkeiten für zukünftige Bitfolgen ermittelt und große Wörterbücher unterstützt. Das PNG-Format verwendet wie Zip das Deflate-Verfahren, das auch für OpenDocument-Dokumente, wie sie OpenOffice.org erstellt, zum Einsatz kommt. Es kombiniert die LZ77-Variante LZSS mit der Huffman-Kodierung.

Rar verwendet Prediction by Partial Matching (PPM), um einzelne Bits vorherzusagen. Die Verfahren der PAQ-Familie verwenden dafür an verschiedene Dateitypen wie Text, Bildformate, Tabelle und ausführbare Programme angepasste Verfahren [5]. Sie arbeiten symmetrisch, benötigen also für Kompression und Dekompression etwa die gleiche Zeit.

Die Verfahren der PAQ8-Familie treiben den Aufwand mit dem Einsatz eines neuronales Netzes auf die Spitze [6],[6],[7]. Der schnellere Nachfolger Zpaq schreibt eine Beschreibung des Algorithmus in die Ausgabe-Datei, um das Problem mit der Vielzahl unterschiedlicher, zueinander inkompatibler PAQ-Versionen zu lösen.

Einige Pack-Programme bieten Multithreading oder fassen mehrere Dateien in einem Archiv zusammen. Während Zip dabei jede Datei einzeln komprimiert, verwenden Programme wie Rar und auf Wunsch auch 7-Zip für alle Dateien ein gemeinsames Wörterbuch, um eine höhere Packdichte zu erzielen.

Ein Archivierer wie Tar ergänzt Komprimier-Programme, die nur einzelne Dateien unterstützen, um diese Funktion. So fasst tar -cvf texte.tar *.txt alle Dateien mit der Endung .txt in das Archiv texte.tar zusammen, das gzip texte.tar als texte.tar.gz komprimiert. Mit der entsprechenden Option leitet Tar die zusammengefügten Dateien automatisch an Gzip, Bzip2, Xz, Lzop, Lzip oder Lzma weiter (Tabelle “Tar-Optionen”).

Tar-Optionen

Programm Kurze Option Lange Option Tar-Version
Gzip -z --gzip ab 1.11.2, März 1993
Bzip2 -j --bzip2 ab 1.13.6, August 1999, als -j ab 1.13.18, Januar 2001
Xz --J --xz ab 1.22.90, Mai 2009
Lzip --lzip ab 1.23, März 2010
Lzop --lzop ab 1.20.90, Juni 2006
Lzma --lzma ab 1.19.1, Oktober 2007

Über die Option -I beziehungsweise --use-compress-program verwenden Sie ein anderes Komprimierprogramm an. Mit der ab Version 1.19.1 verfügbaren Option -a oder --auto-compress ermittelt Tar das Format anhand des Archivnamens automatisch. Beim Entpacken erledigen das aktuelle Tar-Versionen ohne diese Option. Mehr zum Zusammenfassen mehrerer Dateien liefert Howto im Web [8].

Was bringts?

Die hohe Anzahl der Verfahren und Programme erschwert es, für den jeweiligen Zweck eine passende Wahl zu treffen. Hier kommt das im Rahmen des Artikels entwickelte Ruby-Skript Packbench zum Zuge, das eine Datei mit mehreren Programmen packt und dabei Dateigröße, die CPU-Last während des Packens und die Dauer des Vorgangs ermittelt.

Beziehen Sie das Archiv der Version 1.6 oder später von der Heft-DVD oder der Projektseite [9] und entpacken Sie es mit dem Befehl tar -xf Dateiname in einem Terminal. Alternativ beziehen Sie mit git clone git://gitorious.org/packbench/packbench.git die aktuelle Version aus dem Git-Repository [10]. Installieren Sie für Git unter Debian und Ubuntu das Paket git-core und unter OpenSuse git. Für die Programmiersprache Ruby hieven Sie das Paket ruby auf die Platte.

Im Verzeichnis packbench befindet sich das eigentliche Skript packbench, die Konfigurationsdatei packbench-config.rb, das kurze Liesmich README und das Verzeichnis example-benchmarks mit den Protokollen einiger Benchmark-Läufe. Wer Git verwendet, bringt diese Inhalte mit git pull jederzeit auf den aktuellen Stand.

Auf Debian Testing und Ubuntu installieren Sie die Pakete gzip, bzip2, pbzip2, lbzip2, xz-utils, zip, p7zip-full, lzma, lzop, lrzip, rar, paq8l, zp, zpaq. Nutzer anderer Distributionen kompilieren weniger gängige, aktuelle Programme aus dem Quelltext. Sie müssen nicht alle Programme installieren. Das Skript meldet nicht vorhandene Packer, wartet fünf Sekunden und überspringt diese im Benchmark. Mit [Strg]+[C] brechen Sie ab, um die fehlenden Programme vorher noch zu installieren.

Die Konfigurationsdatei packbench-config.rb enthält ein Ruby-Skript. Daher ist wichtig, auf die korrekte Syntax zu achten (Kasten “Packbench-Konfiguration”). Die Konstante FILES enthält eine komma-getrennte Liste der zu packenden Dateien. Standardmäßig verwendet das Skript die etwa 40 MByte große Datei coreutils-8.5.tar, die Sie mit den in Listing 1 gezeigten Befehlen herunter laden und entpacken.

Listing 1

$ wget http://ftp.gnu.org/gnu/coreutils/coreutils-8.5.tar.bz2
$ bunzip2 coreutils-8.5.tar.bz2

Die von den Entwicklern angebotene Xz-Variante entpacken Sie indes mit xz -d coreutils-8.5.tar.xz. Stellen Sie dem Dateinamen in TMPFILE einen Pfad voran, um für die temporären Dateien ein anderes Verzeichnis als das Aktuelle zu verwenden.

Packbench-Konfiguration

#!/usr/bin/ruby env
# Configuration file for packbench
# Temporary file, can be with path
TMPFILE = "packbench-#{Time.now.to_i.to_s}-#{rand(99999).to_s}.tmp"
# Files to compress and decompress
FILES = [
        "coreutils-8.5.tar"
]
# Packers to be used
[...]
PACKERS = [
{
"name" => "gzip",
"extension" => ".gz",
"version" => "gzip --version | head -1",
"compress" => "gzip",
"compressvariants" => [ "-6", "-1", "-9" ],
"decompress" => "gzip -d"
},
[...]
{
"name" => "zip",
"extension" => ".zip",
"version" => "zip --version | grep \"This is\"",
"compress" => "zip COMPRESSVARIANT #{TMPFILE}.zip",
"compressvariants" => [ "-6", "-1", "-9" ],
"decompress" => "unzip"
},
[...]

Unter PACKERS finden Sie bereits viele Packprogramme vorkonfiguriert. Die, die Sie nicht testen möchten, überspringen Sie, in dem Sie im entsprechenden Abschnitt zwischen den geschweiften Klammern die Zeile "skip" => true einfügen. Alle Zeilen im Abschnitt bis auf die letzte müssen mit einem Komma enden.

Möchten Sie einen neuen Packer hinzufügen, schauen in die passende Manpage und tragen analog zu den anderen Einträgen dessen Name (name), die Dateiendung (extension), einen Weg, dessen Version herauszubekommen (version), die Aufrufe fürs Komprimieren (compress) und Dekomprimieren (decompress) sowie die gewünschten unterschiedlichen Pack-Optionen (compressvariants) ein.

Die vorliegenden Einträge enthalten an erster Stelle immer die Standard-Einstellung und dann Optionen für schwächere und stärkere Komprimierung. Für Packer, die den Namen der Archiv-Datei verlangen, bietet sich die Schreibweise bei Zip ein, um mit den Platzhalter COMPRESSVARIANT die Pack-Optionen an der richtigen Stelle einzufügen. Die meisten dieser Optionen stellen die Wörterbuch- oder Blockgröße für die Kompression ein und beeinflussen damit den Speicherverbrauch. Einige Manpages und Hilfetexte der Befehle geben Richtwerte an (Tabelle “Speicherverbrauch”).

Speicherverbrauch

Programm Option Speicherverbrauch
Bzip2, Lbzip2, Pbzip2 -1, -2, …, -9 100, 200, …, 900 KByte
Xz Von -0 bis -9 Etwa 6 bis 800 MByte
Lzip Von -1 bis -9 1 bis 32 MByte, bis 512 MByte möglich (-s)
ZP -1, -2, -3 38, 111, 246 MByte
Paq8l Von -1 bis -8 Von 133 bis 1643 MByte
Zpaq Unter anderem von -cmax.cfg,-1 bis -cmaxcfg,3 Von 130 bis 1861 MByte

Stoppen Sie gegebenenfalls mit /etc/init.d/cron stop oder service cron stop zeitgesteuerte Jobs, um die Ergebnisse nicht zu verfälschen. Schließlich starten Sie den Benchmark mit ./packbench oder ruby packbench (Abbildung 1). Mit ./packbench | tee packbench-2010-08-19.log landet die Ausgabe gleichzeitig auf dem Bildschirm und in einer Datei.

Abbildung 1: Ein erster Benchmark während der Testphase.

Abbildung 1: Ein erster Benchmark während der Testphase.

Ergebnisse

Das Programm gibt am Ende eines Durchlaufs nach allgemeinen Informationen wie dem verwendeten Prozessor und die Versionen der Packprogramme die eigentlich Benchmark-Ergebnisse im Form einer Tabulator-getrennten CSV-Tabelle aus (Abbildung 2). Die ausgeschnittenen und in eine eigene Datei mit der Endung .csv gespeicherten Tabellenzeilen lesen Sie in OpenOffice Calc ein. Wählen Sie im Dialog Textimport als Zeichensatz UTF-8 oder Westeuropa (ISO-8859-15/EURO). Als Trennzeichen wählen Sie unter Trennoptionen den Tabulator als Trennzeichen aus.

Abbildung 2: Packbench gibt den Prozessor, die Kernel-Version, die Packer-Versionen, die Original-Dateigröße und die Ergebnisse der Packer-Läufe aus.

Abbildung 2: Packbench gibt den Prozessor, die Kernel-Version, die Packer-Versionen, die Original-Dateigröße und die Ergebnisse der Packer-Läufe aus.

Die Vorschau sollte die Spalten nun richtig anzeigen (Abbildung 3). Vor dem Klick auf OK wählen Sie für die Spalten mit Dezimalzahlen (Size%, P-Time, U-Time) im Kontextmenü des Spaltentitels als Spaltentyp US-Englisch, damit Calc den Dezimalpunkt durch ein Komma ersetzt.

Abbildung 3: Mit den richtigen Optionen liest OpenOffice Calc die von Packbench ausgegebene Tabelle mit den Ergebnissen ein.

Abbildung 3: Mit den richtigen Optionen liest OpenOffice Calc die von Packbench ausgegebene Tabelle mit den Ergebnissen ein.

Mit Einfügen | Diagramm erstellen Sie aus markierten Daten Diagramme. Nicht nebeneinander liegende Daten markieren Sie mit [Strg]. Kopieren Sie ein Diagramm, öffnen Sie mit Neu | Zeichnung OpenOffice Draw und fügen Sie es dort ein, um es zu exportieren. Auf der DVD der Media-Ausgabe befindet sich als Beispiel die Auswertung der Ergebnisse aus diesem Artikel.

Ergebnisse deuten

In Bezug auf die Größe der gepackten Datei gibt es einen klaren Sieger. Der Packer Paq8l staucht die etwa 40,1 MByte große Original-Datei mit der Option -7 auf 2,82 MByte oder etwa 7 Prozent zusammen (Abbildung 4). Er braucht dazu jedoch selbst auf einen Intel Nehalem i7 980 mit sechs Kernen, von denen er allerdings nur einen nutzt, sowohl beim Packen als auch beim Entpacken über eine Stunde. Das entspricht einer Pack-Geschwindigkeit von etwa 10 KByte/s (Abbildung 5).

Abbildung 4: Klarer Gewinner Paq8l, aber auch ZP, Zpaq und KGB kommen in die Größenordnung rund um 3 MByte.

Abbildung 4: Klarer Gewinner Paq8l, aber auch ZP, Zpaq und KGB kommen in die Größenordnung rund um 3 MByte.

Abbildung 5: Alle Programme bis auf die PAQ-basierten Packer benötigen weniger als eine Minute, oft sogar nur wenige Sekunden, um die Daten zu komprimieren.

Abbildung 5: Alle Programme bis auf die PAQ-basierten Packer benötigen weniger als eine Minute, oft sogar nur wenige Sekunden, um die Daten zu komprimieren.

Auch die anderen Paq-Varianten gehören zu den langsamen, stark komprimierenden Packern, während alle anderen Packprogramme weniger als eine Minute benötigen, jedoch auch größere Dateien abliefern. Am schnellten geht Lzop mit dem Parameter -3 zu Werke, erreicht jedoch mit 15,67 MByte nur gut 39 Prozent der Größe der Originaldatei.

Die LZMA-basierten Programme 7zip, Lzma, dessen Nachfolger Xz sowie Lrzip bieten mit Packzeiten von wenigen Sekunden und Dateigrößen von 4 bis 5 MByte bei stärkeren Pack-Optionen einen guten Kompromiss aus Dateigröße und Geschwindigkeit.

Nur die Bzip2-Varianten Pbzip2 und Lbzip2 nutzen sowohl beim Packen als auch beim Entpacken via Multithreading die Fähigkeiten des Mehrkern-Prozessors, wobei Lbzip2 etwas besser skaliert (Abbildung 6). Der Prozessor bietet sechs Kerne mit Hyperthreading, was zwölf virtuellen Kernen mit je bis zu 100 Prozent Prozessorauslastung entspricht.

Abbildung 6: Nur die Bzip2-Varianten Pbzip2 und Lbzip2 nutzen die Kerne der Hexacore-CPU gut aus.

Abbildung 6: Nur die Bzip2-Varianten Pbzip2 und Lbzip2 nutzen die Kerne der Hexacore-CPU gut aus.

Fazit

Bei der Auswahl eines Packprogrammes spielen neben Performance- und Effizienz-Kriterien auch dessen Verbreitung eine Rolle. Im Linux-Umfeld haben Gzip und Bzip2 eine hohe Verbreitung. Die Multithreading-Alternativen Lbzip2 und Pbzip2 sind zu Bzip2 kompatibel. Einen guten Kompromiss zwischen Dateigröße und Geschwindigkeit liefern die LZMA-basierten Packprogramme, von denen 7-Zip und Xz zu den Bekannteren gehören – letzteres hatten Linux-Entwickler schon als Ersatz für Bzip2 im Gespräch.

Möglichst kleine Dateien in relativ kurzer Zeit liefert Zp mit der Option c3. Wo es mehr auf Geschwindigkeit als auf Platzersparnis ankommt, zum schnellen Entpacken einer Initial Ramdisk beispielsweise, eignet sich Lzop.

Da die Ergebnisse von der Art der Daten abhängen, empfiehlt es sich, Packbench mit den Wunschdaten zu testen. Mit der entsprechenden Konfigurartion misst das Skript auch die Effizienz von Audio- und Videocodecs oder Bild-Optimierern wie Optipng.

Glossar

Threads

Leichtgewichtige Alternativen zu normalen Prozessen.

CSV

Comma/Character Separated Values. Dateiformat mit durch ein Komma oder ein anderes Zeichen getrennten Werten.

Initial Ramdisk

Gepacktes Dateisystem mit Kernel-Module und Skripten, um beim Start eines modularen Kernels die passenden Treiber nachzuladen.

Der Autor

Martin Steigerwald arbeitet als Trainer, Consultant und Systemadministrator bei der team(ix) GmbH in Nürnberg. Schwerpunkte seiner Tätigkeit sind Linux-Schulungen, die Konzeption, Installation und Wartung solider IT-Infrastruktur auf Basis von Debian Linux sowie Second Level Support für Linux als Business-Desktop bei Kunden von teamix(ix).

LinuxUser 10/2010 KAUFEN
EINZELNE AUSGABE
ABONNEMENTS
TABLET & SMARTPHONE APPS
E-Mail Benachrichtigung
Benachrichtige mich zu:

Hinweis: Dieser Artikel ist älter als ein Jahr, enthaltene Informationen sind möglicherweise veraltet.

0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben