Strings komprimieren und dekomprimieren (Thema: PHP Beispiele)

Möglichkeiten, Strings in PHP zu komprimieren und die Komprimierung wieder umzukehren

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-Code
<?php
	$str = 'eins eins eins zwei zwei zwei drei drei drei';
	$compressed = gzcompress($str, 9); // maximale Komprimierung
	var_dump(strlen($str), strlen($compressed));
?>

HTML-Code: Ausgabe
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-Code
<?php
	$str = 'abcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefg';
	$compressed = gzcompress($str);
	$uncompressed = gzuncompress($compressed);
	echo($uncompressed);
?>

HTML-Code: Ausgabe
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-Code
<?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&auml;nge<br /><span class="minor">(unkomprimiert)</span></th>
			<th>L&auml;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>

Kommentare (0)

Von neu nach alt