Entwicklung eines datenkomprimierenden Dienstprogramms auf Basis von Huffman-Codes mit Haskell
(lazamar.github.io)Implementierung eines Datenkomprimierungsprogramms mit Huffman-Codierung
- Was ist ein Huffman-Code?
- Führt Datenkomprimierung durch, indem jedes Zeichen einer eindeutigen Bitsequenz zugeordnet wird
- Häufig vorkommende Zeichen werden auf kurze Bitsequenzen abgebildet, seltene Zeichen auf lange Bitsequenzen
- Beispiel: Beim String
aaabwirdaauf1undbauf0abgebildet und so zu1110komprimiert
Präfixfreier Code
- Was ist ein präfixfreier Code?
- Kein Codewort darf Präfix eines anderen Codeworts sein
- Beispiel: Bei
aaabcwirdaauf1,bauf00undcauf01abgebildet und so zu1110001komprimiert
Erzeugung präfixfreier Codes
- Methode zur Erzeugung präfixfreier Codes
- Alle Zeichen werden als Blätter in einem vollständigen Binärbaum angeordnet
- Der linke Ast wird mit
1, der rechte Ast mit0beschriftet - Der Pfad von der Wurzel zum Blatt beschreibt das Codewort jedes Zeichens
Schreiben des Encoders
-
Typdefinitionen
- Definition der Typen
Bit,Code,FreqMap,CodeMap,Weight,HTree HTreebesteht ausLeafundFork
- Definition der Typen
-
Encoding-Funktion
- Funktion zur Umwandlung eines Strings in Bits
- Berechnet mit
FreqMapdie Häufigkeit jedes Zeichens und erzeugt darauf basierend einen Huffman-Baum - Erzeugt aus dem Huffman-Baum das Codewort für jedes Zeichen
-
Decoding-Funktion
- Funktion zur Rückumwandlung von Bits in den ursprünglichen String
- Dekodiert Bits sequenziell mithilfe des Huffman-Baums
Anbindung an Binärdateien
- Encoding binärer Daten
- Liest Bytes als Zeichen mit dem Modul
Data.ByteString.Char8 - Kodiert binäre Daten mit dem Text-Encoder
- Liest Bytes als Zeichen mit dem Modul
Serialisierung
- Serialisierungsfunktion
- Wandelt
FreqMapund Bits in tatsächliche Bytes um und speichert sie in einer Datei - Erzeugt mit der
Put-Monade effizient einByteString
- Wandelt
Deserialisierung
- Deserialisierungsfunktion
- Wandelt aus einer Datei gelesene Daten in
FreqMapund Bits um - Deserialisiert
FreqMapmit derGet-Monade
- Wandelt aus einer Datei gelesene Daten in
Integration des gesamten Codes
- Funktionen zum Komprimieren und Entpacken von Dateien
compress-Funktion: Liest eine Datei, erzeugt eine Frequenz-Map, kodiert die Daten und speichert sie als komprimierte Dateidecompress-Funktion: Liest eine komprimierte Datei, dekodiert die Daten und speichert sie wieder als ursprüngliche Datei
Verbesserungen
-
Multithreading
- Dekodiert Dateiabschnitte parallel
- Ermöglicht Parallelverarbeitung durch Hinzufügen einer Tabelle, die Abschnittsgrenzen und die erwartete Dekodierungsgröße angibt
-
Single-Pass-Encoding
- Erzeugt die Frequenz-Map während des Encodings in Echtzeit
- Es ist nicht nötig, die Frequenz-Map am Anfang der Datei einzubetten
-
Kanonische Huffman-Codes
- Dekodiert mit
O(1)Zeitkomplexität durch Indexierung eines Vektors statt durch Traversierung des Baums
- Dekodiert mit
-
Schnellere Codeerzeugung
- Falls Single-Pass-Encoding versucht wird, muss die Erzeugung der Codemap beschleunigt werden
Meinung von GN⁺
-
Vorteile der Huffman-Codierung
- Ermöglicht effiziente Datenkomprimierung, indem häufig vorkommende Zeichen auf kurze Bitsequenzen abgebildet werden
- Kann große Datenmengen verarbeiten und dabei den Speicherverbrauch minimieren
-
Vorteile von Haskell
- Ermöglicht modularen Code durch Nutzung der Vorteile der funktionalen Programmierung
- Kann den Speicherverbrauch durch Lazy Evaluation optimieren
-
Projekte mit ähnlicher Funktionalität
- Es gibt verschiedene Datenkomprimierungswerkzeuge wie gzip und bzip2
- Es ist wichtig, die Vor- und Nachteile der einzelnen Werkzeuge zu vergleichen und das passende auszuwählen
-
Aspekte bei der Einführung neuer Technologien
- Der geeignete Algorithmus sollte unter Berücksichtigung von Performance und Speicherverbrauch gewählt werden
- Die Effizienz kann durch den Einsatz von Optimierungstechniken wie Single-Pass-Encoding erhöht werden
1 Kommentare
Hacker-News-Kommentare
Es gibt einen arraybasierten In-Place-Algorithmus, der den Bedarf reduziert, Bäume zu allokieren und Zeigern zu folgen
Dass sichergestellt werden muss, dass ein Codewort nicht zum Präfix eines anderen Codeworts wird, ist technisch nicht korrekt
Es wird gefragt, ob es ein ähnliches Tutorial gibt, das fortgeschrittenere Funktionen zum Schreiben von Haskell-Programmen behandelt, etwa Monad-Transformer, Lenses usw.
Im funktionalen Programmierkurs von Coursera (Scala) gibt es eine ähnliche Huffman-Coding-Aufgabe
Mit Huffman-Codes wurde ein MICMAC-Prozessor-Makroprogramm mit einer minimalen Anzahl von Mikrozyklen und Mikroinstruktionen ausgeführt
Weitere Informationen zu Huffman-Coding: Rosetta Code Huffman Coding
Frage an Haskell-Programmierer: Wie steht es um die Performance von Haskell für Entwickler, die optimierten Code schreiben wollen?
Ein Kommentar bedankt sich fürs Teilen
In der Tabelle im Abschnitt "Creating prefix-free codes" gibt es einen Tippfehler
Arithmetische Codes sind in fast jeder Hinsicht besser