Bisher speichere ich Text-Untertitel (meist im SubRip Format) als Base64-codierten String, der vorher mit zlib komprimiert ist, in einer MongoDB Datenbank. Auf der Debconf12 wurde vor kurzem diskutiert, ob man von gzip (zlib) auf xz (lzma/lzma2) umsteigen soll, um das Debian Archiv einzudampfen (derzeit 615 GB).
Dabei kam mir der Gedanke, vielleicht auch umzusteigen und zukünftig Untertitel vor dem Speichern in MongoDB mit xz zu komprimieren damit die Datenbank nicht explodiert. Aber nur weil das für Debian vielleicht von Vorteil ist, muss das in meinem Fall nicht auch so sein. Es gilt also selbst Tests durchzuführen.
Ein handvoll Untertitel zum Testen vorbereiten
$ find /media/master/Movies/ -name *.srt -exec cp "{}" /srv/subtitles/ \; $ du -ch /srv/subtitles/*.srt 31M total $ ls -l /srv/subtitles/ | wc -l 508 $ ls -l /srv/subtitles/ | awk '{s+=$5} END {print "Average file size: " s/NR/1024 "k"}' Average file size: 58.1365k
Zum Testen sind also 508 Untertiteldateien vorhanden, die insgesamt eine Größe von 31 MB haben. SubRip Dateien sind in der Regel zwischen 40 und 100 KB groß, wie man auch unter "Average file size" sieht.
Mit xz komprimieren
$ time xz -k /srv/subtitles/*.srt real 0m29.131s user 0m26.670s sys 0m0.216s $ du -ch /srv/subtitles/*.xz 9.7M total
Mit bzip2 komprimieren
$ time bzip2 -k /srv/subtitles/*.srt real 0m7.469s user 0m6.536s sys 0m0.308s $ du -ch /srv/subtitles/*.bz2 9.2M total
Mit gzip komprimieren
$ time gzip /srv/subtitles/*.srt real 0m4.660s user 0m4.308s sys 0m0.148s $ du -ch /srv/subtitles/*.gz 12M total
xz soll angeblich sehr effektiv im Eindampfen sein, das, wie man hier sieht, nicht der Fall ist. Bei bereits nur 508 Untertiteln, spart bzip2 gegenüber gzip 2,8 MB ein und gegenüber xz 0,5 MB und braucht zeitlich nur gering länger als gzip. Bei xz dauert das schon sehr viel länger.
Da Untertitel meist nur einzeln und nicht in Bulk in MongoDB gespeichert werden, kann der Zeitverlust vernachlässigt werden:
Einzelnen Untertitel komprimieren
$ ls -lh subtitle.srt 65K Jul 29 18:28 subtitle.srt $ time xz -k subtitle.srt real 0m0.093s user 0m0.064s sys 0m0.020s $ time bzip2 -k subtitle.srt real 0m0.021s user 0m0.004s sys 0m0.012s $ time gzip subtitle.srt real 0m0.016s user 0m0.008s sys 0m0.004s $ ls -alhS --reverse 21K Jul 29 18:28 subtitle.srt.bz2 22K Jul 29 18:28 subtitle.srt.xz 27K Jul 29 18:28 subtitle.srt.gz
Dauert alles weniger als 200 ms, ab wann es für den Menschen spürbar wird, was Latenz betrifft....
Versuch mit größeren Dateien
$ wget 'http://cachefly.cachefly.net/100mb.test' -O 100M.tar
Das Testfile von Cachefly beinhaltet sehr viele Textdateien.
$ tar tfv 100M.tar
Mit xz komprimieren
$ time xz -k 100M.tar real 0m53.034s user 0m51.811s sys 0m0.296s
Mit bzip2 komprimieren
$ time bzip2 -k 100M.tar real 0m21.024s user 0m20.761s sys 0m0.092s
Mit gzip komprimieren
$ time gzip 100M.tar real 0m2.762s user 0m2.488s sys 0m0.136s
Resultat
$ ls -alhS --reverse 44K Feb 28 2005 100M.tar.xz 1.5M Feb 28 2005 100M.tar.bz2 4.5M Feb 28 2005 100M.tar.gz
In diesem Fall hat xz also ganze Arbeit geleistet und 100 MB in nur 44 KB eingestampft. Bei Kompression kommt es natürlich immer darauf an, welche Art von Daten man schrumpfen will. So wie es aussieht, ist für kleine Textdateien < 900 KB bzip2 die beste Wahl. Bei sehr viel größeren Dateien wie z.B. Logfiles oder auch Binary Files zeigt xz seine Stärken.
D.h. zum Speichern der Untertitel ist in diesem Anwendungsfall bzip2 der geeignetere Kandidat. Den Code umzustricken dürfte eine Kleinigkeit sein, da die API der Python Module gleich aufgebaut ist:
- http://docs.python.org/dev/library/zlib.html
- http://docs.python.org/dev/library/bz2.html#one-shot-de-compression
Ein
$ sed -i 's/zlib\.compress/bz2\.compress/g' *.py $ sed -i 's/zlib\.decompress/bz2\.decompress/g' *.py
wäre warscheinlich schon alles...
Links
- http://stackoverflow.com/questions/1413595/sending-text-file-over-network-with-high-compression
- http://tukaani.org/lzma/benchmarks.html
- http://parezcoydigo.wordpress.com/2011/10/09/clustering-with-compression-for-the-historian/
- http://ivoras.net/blog/tree/2010-07-15.what-to-use-for-log-compression.html
- http://blog.terzza.com/linux-compression-comparison-gzip-vs-bzip2-vs-lzma-vs-zip-vs-compress/