Rolf B: PHP::serialize() - Zu hoher Speicherverbrauch - Alternativen?

Beitrag lesen

Hallo Raketenbastler,

Tom ist auf dem richtigen Weg, es geht aber einfacher. Man kann ein Array relativ einfach elementweise serialisieren und dabei die String-Struktur beibehalten, die serialize() erzeugt. Dann kann man stumpf mit unserialize() wieder einlesen. Wenn auch unserialize platzt, könnte man eine Funktion stream_unserialize schreiben. Dafür muss man allerdings noch ein bisschen mehr das Serialisierungsformat von PHP erforschen.

Ein serialisiertes Array beginnt mit "a:n:{" und endet mit "}". n ist die Anzahl der Elemente. Dazwischen finden sich die Keys und Values des Arrays. Ein skalarer Wert wird dabei mit einem ; abgeschlossen, ein Arraywert nicht. Das muss einen aber nicht kümmern, das erledigt die PHP serialize()-Funktion automagisch.

Das folgende Beispiel zeigt es mit echo, statt dessen kannst Du auch fwrite nehmen um in eine Datei zu schreiben. Oder einen Callback übergeben, der sich um das Speichern der serialisierten Fragmente kümmert.

Für eine produktionsreife Version müsste man auch noch prüfen, welcher Typ übergeben wurde, und dann einen passenden Streamserializer dafür verwenden.

function stream_serialize($arr) {
    echo "a:" . count($arr) . ":{";
    foreach ($arr as $k => $v) {
        echo serialize($k).serialize($v);
    }
    echo "}";
}

Wenn man statt des Echo die Teilergebnisse in einem String sammelt, muss man String-Operationen ausführen. Das Verketten zweier Strings benötigt doppelten Speicher, weil man die beiden Originalstrings braucht und dazu Speicher für den Ziel-String. Hinzu kommt das $bigArray. Beim Deserialisieren braucht man nur den Gesamtstring, den man aus der Datei gesaugt hat, und das Array. Ein Array vergrößert sich sparsamer als ein String, weil man dabei nur eine Liste von Zeigern auf Arrayeinträge vergrößeren muss.

Es kann auch sein, dass die wiederkehrenden Operationen mit großen Strings viel Zeit gekostet haben. Wenn man Eintrag für Eintrag serialisiert, könnte es unter dem Strich schneller sein. Keine Ahnung, muss man testen.

Rolf

--
sumpsi - posui - obstruxi