1. gzcompress()
Mit der Funktion gzcompress($data, $level) kann ein String komprimiert werden, zum Beispiel um beim Speichern in einer Datei Platz zu sparen. Übergeben werden muss der String als erster Parameter ($data). Optional kann über $level eine Komprimierungsstärke zwischen 0 und 9 (Integer) angegeben werden. Der Standardwert liegt bei 6 und liefert in der Regel einen guten Kompromiss zwischen Geschwindigkeit und Platzersparnis.
<?php $str = 'eins eins eins zwei zwei zwei drei drei drei'; $compressed = gzcompress($str, 9); // maximale Komprimierung var_dump(strlen($str), strlen($compressed)); ?>
int(44) int(25)
2. gzdecompress()
Bereits komprimierte Daten können mit der Funktion gzuncompress($data) wieder dekomprimiert werden. Das Angeben der Komprimierungsstärke ist in diesem Fall nicht mehr notwendig.
<?php $str = 'abcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefg'; $compressed = gzcompress($str); $uncompressed = gzuncompress($compressed); echo($uncompressed); ?>
abcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefg
3. Analyse der Komprimierungsstärke und Performance von gzcompress() und gzuncompress()
Die nachfolgende Tabelle enthält eine Analyse der Komprimierungsstärke von gzcompress(), sowie der Performance von gzcompress() und gzuncompress(), abhängig von der gewählten Komprimierungsstärke (0-9). Es wurde dazu ein beispielhafter Lorem-Ipsum-Text erzeugt, der aus 100 nahezu gleichen Blöcken bestand. Bei jedem Block wurden jeweils 10 zufällige Zeichen durch „x” ersetzt, um die Komprimierung etwas zu erschweren. Zusammengerechnet umfasste der gesamte zu komprimierende Text 17600 Zeichen. Wie in der Tabelle zu sehen ist, wurde dieser bei Stärke 8 und 9 zu einem Text mit 2057 Zeichen Länge komprimiert (ca. 88% Kompression). 5000 mal die Kompression auf Stufe 9 durchzuführen hat im Testsystem ca. 4,5 Sekunden benötigt (ca. 0,9ms pro Iteration). 5000 mal die Daten wieder zu dekomprimieren hat bei Stufe 9 knapp 0,87 Sekunden gedauert. Offenbar ist die Dekomprimierung weitestgehend unabhängig von der gewählten Komprimierungsstärke.
Level | Länge (unkomprimiert) |
Länge (komprimiert) |
Kompression | 5000 mal gzcompress() |
5000 mal gzuncompress() |
---|---|---|---|---|---|
0 | 17600 | 17611 | -0.06% | 0.2837s | 0.0683s |
1 | 17600 | 3581 | 79.65% | 0.8852s | 0.9455s |
2 | 17600 | 3246 | 81.56% | 0.9508s | 0.8559s |
3 | 17600 | 3057 | 82.63% | 1.0467s | 0.8068s |
4 | 17600 | 2742 | 84.42% | 1.6389s | 0.7532s |
5 | 17600 | 2322 | 86.81% | 2.0733s | 0.6428s |
6 | 17600 | 2188 | 87.57% | 2.622s | 0.9054s |
7 | 17600 | 2093 | 88.11% | 3.3705s | 0.8804s |
8 | 17600 | 2057 | 88.31% | 4.4997s | 0.8653s |
9 | 17600 | 2057 | 88.31% | 4.5151s | 0.8627s |
Die Tabelle wurde mit folgendem Code erzeugt:
<?php // Anzahl der Iterationen bei der Zeitmessung define('ITERATIONS', 5000); // Lorem-Ipsum-Basis $lorem = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.'; // Variable fuer den Text der spaeter komprimiert werden soll $str = ''; // Zufallsgenerator seeden, sodass jeder Durchlauf gleich ist mt_srand(10000); // Text aus 100 Lorem-Ipsum-Bloecken zusammensetzen for ($x=0; $x<100; $x++) { $tmp = $lorem; // Bei jedem Block 10 kleinere Aenderungen durchfuehren for ($y=0; $y<10; $y++) { $pos = mt_rand(0, strlen($tmp)-1); $tmp[$pos] = 'x'; } // Block zum bisherigen Text hinzufuegen $str .= $tmp . ' '; } // Funktion, die den Zeitbedarf fuer des Komprimieren bei x Iterationen misst function calculateTimeCompress($str, $level, $iterations) { $starttime = microtime(true); for ($x=0; $x<$iterations; $x++) { gzcompress($str, $level); } return round(microtime(true) - $starttime, 4); } // Funktion, die den Zeitbedarf fuer des Dekomprimieren bei x Iterationen misst function calculateTimeUncompress($str, $iterations) { $starttime = microtime(true); for ($x=0; $x<$iterations; $x++) { gzuncompress($str); } return round(microtime(true) - $starttime, 4); } ?> <table id="php-gzcompress-table"> <thead> <tr> <th>Level</th> <th>Länge<br /><span class="minor">(unkomprimiert)</span></th> <th>Länge<br /><span class="minor">(komprimiert)</span></th> <th>Kompression</th> <th><?php echo ITERATIONS; ?> mal<br />gzcompress()</th> <th><?php echo ITERATIONS; ?> mal<br />gzuncompress()</th> </tr> </thead> <tbody> <?php foreach (range(0, 9) as $level): ?> <?php $compressed = gzcompress($str, $level); ?> <tr> <td><?php echo $level; ?></td> <td><?php echo strlen($str); ?></td> <td><?php echo strlen($compressed); ?></td> <td><?php echo round(1 - (strlen($compressed)/strlen($str)), 4)*100; ?>%</td> <td><?php echo calculateTimeCompress($str, $level, ITERATIONS); ?>s</td> <td><?php echo calculateTimeUncompress($compressed, ITERATIONS); ?>s</td> </tr> <?php endforeach; ?> </tbody> </table>