Bevorzugte Methode zum Speichern von PHP-Arrays (json_encode vs. serialize)

Lesezeit: 10 Minuten

Bevorzugte Methode zum Speichern von PHP Arrays json encode vs serialize
Kyle Farris

Ich muss ein mehrdimensionales assoziatives Array von Daten zu Caching-Zwecken in einer Flatfile speichern. Ich könnte gelegentlich auf die Notwendigkeit stoßen, es für die Verwendung in meiner Webanwendung in JSON zu konvertieren, aber die überwiegende Mehrheit der Zeit werde ich das Array direkt in PHP verwenden.

Wäre es effizienter, das Array als JSON oder als PHP-serialisiertes Array in dieser Textdatei zu speichern? Ich habe mich umgesehen und es scheint, dass in den neuesten Versionen von PHP (5.3) json_decode ist eigentlich schneller als unserialize.

Ich neige derzeit dazu, das Array als JSON zu speichern, da ich das Gefühl habe, dass es bei Bedarf von einem Menschen leichter gelesen werden kann. Es kann mit sehr geringem Aufwand sowohl in PHP als auch in JavaScript verwendet werden, und nach dem, was ich gelesen habe, könnte es sogar so sein schneller zu decodieren (obwohl ich mir nicht sicher bin, was die Codierung betrifft).

Kennt jemand Fallstricke? Hat jemand gute Benchmarks, um die Leistungsvorteile beider Methoden zu zeigen?

  • Warum nicht einfach so etwas tun: $array = array('foo' => 'bar'); file_put_contents('foo.php', "<?php return ".var_export($array, true) . ";"); . und . $array = file_get_contents('foo.php'))); Natürlich, wenn dies für viel größere Datenmengen ist, würde ich wahrscheinlich mit … CSV gehen. Also vielleicht nicht das sexyste – aber es gibt es aus gutem Grund schon länger als uns beide – und es gibt eine hervorragende Unterstützung in PHP für den teilweisen oder gestreamten Zugriff auf wirklich große Datensätze.

    – Christoffer Bubach

    30. Juli 2021 um 16:34 Uhr


1646891651 367 Bevorzugte Methode zum Speichern von PHP Arrays json encode vs serialize
Peter Bailey

Kommt auf deine Prioritäten an.

Wenn Leistung Ihre absolute Fahreigenschaft ist, dann nehmen Sie auf jeden Fall den Schnellsten. Stellen Sie einfach sicher, dass Sie die Unterschiede vollständig verstanden haben, bevor Sie eine Wahl treffen

  • nicht wie serialize() Sie müssen zusätzliche Parameter hinzufügen, um UTF-8-Zeichen unberührt zu lassen: json_encode($array, JSON_UNESCAPED_UNICODE) (Andernfalls werden UTF-8-Zeichen in Unicode-Escape-Sequenzen konvertiert).
  • JSON hat keine Erinnerung an die ursprüngliche Klasse des Objekts (sie werden immer als Instanzen von stdClass wiederhergestellt).
  • Sie können nicht aushebeln __sleep() und __wakeup() mit JSON
  • Standardmäßig werden nur öffentliche Eigenschaften mit JSON serialisiert. (in PHP>=5.4 kannst du umsetzen JsonSerializable um dieses Verhalten zu ändern).
  • JSON ist portabler

Und es gibt wahrscheinlich noch ein paar andere Unterschiede, die mir im Moment nicht einfallen.

Ein einfacher Geschwindigkeitstest, um die beiden zu vergleichen

<?php

ini_set('display_errors', 1);
error_reporting(E_ALL);

// Make a big, honkin test array
// You may need to adjust this depth to avoid memory limit errors
$testArray = fillArray(0, 5);

// Time json encoding
$start = microtime(true);
json_encode($testArray);
$jsonTime = microtime(true) - $start;
echo "JSON encoded in $jsonTime seconds\n";

// Time serialization
$start = microtime(true);
serialize($testArray);
$serializeTime = microtime(true) - $start;
echo "PHP serialized in $serializeTime seconds\n";

// Compare them
if ($jsonTime < $serializeTime) {
    printf("json_encode() was roughly %01.2f%% faster than serialize()\n", ($serializeTime / $jsonTime - 1) * 100);
}
else if ($serializeTime < $jsonTime ) {
    printf("serialize() was roughly %01.2f%% faster than json_encode()\n", ($jsonTime / $serializeTime - 1) * 100);
} else {
    echo "Impossible!\n";
}

function fillArray( $depth, $max ) {
    static $seed;
    if (is_null($seed)) {
        $seed = array('a', 2, 'c', 4, 'e', 6, 'g', 8, 'i', 10);
    }
    if ($depth < $max) {
        $node = array();
        foreach ($seed as $key) {
            $node[$key] = fillArray($depth + 1, $max);
        }
        return $node;
    }
    return 'empty';
}

  • “JSON konvertiert UTF-8-Zeichen in Unicode-Escape-Sequenzen.” Nicht mehr unbedingt wahr: Wir haben jetzt JSON_UNESCAPED_UNICODE.

    – TRIG

    24. November 2012 um 17:01 Uhr

  • Hier sind wir fast 5 Jahre später und ich habe die Tests erneut durchgeführt (nur die json_encode) und es ist im Durchschnitt etwa 131 % schneller als die Serialisierung jetzt. Es muss also einige ziemlich nette Verbesserungen dieser Funktion in 5.4.x gegenüber 5.3.x geben. Insbesondere führe ich 5.4.24 auf CentOS 6 aus. Also, yay für JSON !!

    – Kyle Farris

    7. März 2014 um 21:56 Uhr


  • In meinem Fall codieren wir einmal und decodieren viel, also haben wir json_decode vs. unserialize verglichen und die Ergebnisse waren JSON-dcodiert in 0,06662392616272 Sekunden.
    PHP deserialisiert in 0,093269109725952 Sekunden.

    Benutzer1642018

    28. Juli 2014 um 3:05 Uhr

  • Interessant: Wenn Sie diesen Code weiter ausführen 3v4l.orglaufen die neuesten PHP7-Entwicklungs-Builds serialize schneller als json_encode: „serialize() war ungefähr 76,53 % schneller als json_encode()“

    – marcvangend

    9. März 2015 um 12:46 Uhr

  • 2017, PHP 7.1 und serialize() was roughly 35.04% faster than json_encode()

    – Elias Soares

    25. Oktober 2017 um 17:01 Uhr

JSON ist einfacher und schneller als das Serialisierungsformat von PHP und sollte verwendet werden wenn nicht:

  • Sie speichern tief verschachtelte Arrays:
    json_decode(): “Diese Funktion gibt “false” zurück, wenn die JSON-codierten Daten tiefer als 127 Elemente sind.”
  • Sie speichern Objekte, die als die richtige Klasse deserialisiert werden müssen
  • Sie interagieren mit alten PHP-Versionen, die json_decode nicht unterstützen

  • Gute Antwort. Haha, 127 Level tief scheint ein bisschen verrückt zu sein; Zum Glück gehe ich nur wie 2-3 höchstens. Haben Sie Daten, die die Tatsache belegen, dass json_decode/json_encode schneller ist als unserialize/serialize?

    – Kyle Farris

    29. April 2009 um 20:34 Uhr

  • Ich habe es vor einiger Zeit getestet und json kam schneller heraus – ich habe die Daten jedoch nicht mehr.

    – Greg

    29. April 2009 um 21:02 Uhr

  • „5.3.0 Optionale Tiefe hinzugefügt. Die Standard-Rekursionstiefe wurde von 128 auf 512 erhöht.“

    – giorgio79

    15. Dezember 2011 um 6:30 Uhr

  • Ich würde der obigen Liste noch einen Punkt hinzufügen: json_encode() sollte nicht verwendet werden, wenn Ihre Daten möglicherweise ungültige UTF-8-Bytesequenzen enthalten. Für solche Daten gibt es einfach false zurück. Versuchen Sie es zum Beispiel mit: var_dump(json_encode(“\xEF\xEF”));

    – pako

    20. Mai 2015 um 20:28 Uhr


  • Es stimmt nicht, dass es im Allgemeinen schneller ist. Wenn Sie ein kleines Array mit etwa 500 Einträgen haben, ist unserialisieren/serialisieren tatsächlich 200-400 % schneller als json_decode/json_encode (PHP 5.6.19).

    – Adam

    12. August 2016 um 6:51 Uhr

Bevorzugte Methode zum Speichern von PHP Arrays json encode vs serialize
Taco

Zu diesem Thema habe ich einen Blogpost geschrieben: “Ein großes Array zwischenspeichern: JSON, serialisieren oder var_export?“. In diesem Beitrag wird gezeigt, dass die Serialisierung die beste Wahl für kleine bis große Arrays ist. Für sehr große Arrays (> 70 MB) ist JSON die bessere Wahl.

  • Der Link ist nicht mehr verfügbar.

    – Martin Thoma

    28. Februar 2015 um 5:35 Uhr

  • Danke Elch, ich habe den Link aktualisiert. Obwohl der Artikel fast 6 Jahre alt ist und für aktuelle PHP-Versionen möglicherweise nicht so genau ist.

    – Tacos

    2. März 2015 um 10:04 Uhr

  • Ich habe einige Tests durchgeführt und eine einfache Funktion zum Testen erstellt, mit großen Arrays (verwendete Funktion von Peter Bailey für diese). json_encode() handelt von 80 % bis 150 % schneller (es geht dort wirklich auf und ab) als serialize(), mit etwa 300 Iterationen. Aber bei Verwendung der kleineren Arrays (array("teams" => array(1 => array(4 arrays of players), 2 => array(4 arrays of players)))), habe ich getestet mit 750.000 Iterationen u serialize() handelt von 6 % bis 10 % schneller in dem Fall. Meine Funktion nimmt die Durchschnittszeiten für alle Iterationen und vergleicht sie. Ich könnte es hier als eine der Antworten posten

    – MiChAeLoKGB

    23. Mai 2015 um 23:36 Uhr


  • wenn die Daten nur von PHP verwendet werden, ist var_export mein Ding. Man muss nur auf mögliche Syntaxfehler im Include-Gedanken achten.

    – Gfra54

    15. Oktober 2015 um 10:14 Uhr

  • Blog gibt es nicht mehr

    – Popeye

    3. Oktober 2018 um 11:50 Uhr

Y hat gerade die serialisierte und json-Codierung und -Decodierung getestet, plus die Größe, die die gespeicherte Zeichenfolge benötigt.

JSON encoded in 0.067085981369 seconds. Size (1277772)
PHP serialized in 0.12110209465 seconds. Size (1955548)
JSON decode in 0.22470498085 seconds
PHP serialized in 0.211947917938 seconds
json_encode() was roughly 80.52% faster than serialize()
unserialize() was roughly 6.02% faster than json_decode()
JSON string was roughly 53.04% smaller than Serialized string

Wir können daraus schließen, dass JSON schneller kodiert und einen kleineren String ergibt, aber Deserialize ist schneller beim Dekodieren des Strings.

  • Wie wäre es mit heute? Jetzt, wo wir PHP 7.*.* und sogar PHP 8.*.* haben? Sollten wir igbinary ausprobieren? Danke!

    – Tonix

    13. Mai 2021 um 5:34 Uhr


Wenn Sie Informationen zwischenspeichern, die Sie letztendlich zu einem späteren Zeitpunkt “einbeziehen” möchten, sollten Sie versuchen, sie zu verwenden var_export. Auf diese Weise nehmen Sie den Treffer nur beim “serialisieren” und nicht beim “unserialisieren”.

  • Dies ist höchstwahrscheinlich der schnellste Weg, der möglich ist. Ich habe ein Beispiel zum SO “PHP – schnell serialisieren/deserialisieren”: stackoverflow.com/questions/2545455/…

    – dave1010

    30. Juli 2010 um 8:56 Uhr


1646891652 864 Bevorzugte Methode zum Speichern von PHP Arrays json encode vs serialize
Jeff Whiting

Ich habe den Test um die Deserialisierungsleistung erweitert. Hier sind die Zahlen, die ich bekommen habe.

Serialize

JSON encoded in 2.5738489627838 seconds
PHP serialized in 5.2861361503601 seconds
Serialize: json_encode() was roughly 105.38% faster than serialize()


Unserialize

JSON decode in 10.915472984314 seconds
PHP unserialized in 7.6223039627075 seconds
Unserialize: unserialize() was roughly 43.20% faster than json_decode() 

Json scheint also schneller zum Codieren, aber langsam zum Decodieren zu sein. Es könnte also von Ihrer Anwendung abhängen und davon, was Sie am meisten erwarten.

  • Dies ist höchstwahrscheinlich der schnellste Weg, der möglich ist. Ich habe ein Beispiel zum SO “PHP – schnell serialisieren/deserialisieren”: stackoverflow.com/questions/2545455/…

    – dave1010

    30. Juli 2010 um 8:56 Uhr


1646891652 137 Bevorzugte Methode zum Speichern von PHP Arrays json encode vs serialize
Gemeinschaft

Wirklich schönes Thema und nachdem ich die wenigen Antworten gelesen habe, möchte ich meine Experimente zu diesem Thema teilen.

Ich habe einen Anwendungsfall, bei dem fast jedes Mal, wenn ich mit der Datenbank spreche, eine “riesige” Tabelle abgefragt werden muss (fragen Sie nicht warum, nur eine Tatsache). Das Datenbank-Caching-System ist nicht geeignet, da es die verschiedenen Anforderungen nicht zwischenspeichert, also dachte ich über PHP-Caching-Systeme nach.

Ich habe es versucht apcu aber es entsprach nicht den Anforderungen, der Speicher ist in diesem Fall nicht zuverlässig genug. Der nächste Schritt war das Zwischenspeichern in eine Datei mit Serialisierung.

Die Tabelle hat 14355 Einträge mit 18 Spalten, das sind meine Tests und Statistiken zum Lesen des serialisierten Caches:

JSON:

Wie Sie alle sagten, die größten Unannehmlichkeiten mit json_encode/json_decode ist, dass es alles in ein verwandelt StdClass Instanz (oder Objekt). Wenn Sie es durchlaufen müssen, werden Sie es wahrscheinlich in ein Array umwandeln, und ja, es erhöht die Umwandlungszeit

Durchschnittszeit: 780,2 ms; Speicherverbrauch: 41,5 MB; Cache-Dateigröße: 3,8 MB

Nachrichtenpaket

@hutch erwähnt Nachrichtenpaket. Hübsche Webseite. Probieren wir es aus, sollen wir?

Durchschnittszeit: 497 ms; Speicherverbrauch: 32 MB; Cache-Dateigröße: 2,8 MB

Das ist besser, erfordert aber eine neue Erweiterung; Kompilieren manchmal ängstliche Menschen …

IgBinär

@GingerDog erwähnt binär. Beachten Sie, dass ich die eingestellt habe igbinary.compact_strings=Offweil ich mich mehr um die Leseleistung als um die Dateigröße kümmere.

Durchschnittszeit: 411,4 ms; Speicherverbrauch: 36,75 MB; Cache-Dateigröße: 3,3 MB

Besser als msg-Paket. Trotzdem muss auch dieser kompiliert werden.

serialize/unserialize

Durchschnittszeit: 477,2 ms; Speicherverbrauch: 36,25 MB; Cache-Dateigröße: 5,9 MB

Bessere Leistung als JSON, je größer das Array ist, desto langsamer json_decode ist, aber das ist dir schon neu.

Diese externen Erweiterungen schränken die Dateigröße ein und scheinen auf dem Papier großartig zu sein. Zahlen lügen nicht*. Was bringt es, eine Erweiterung zu kompilieren, wenn Sie fast die gleichen Ergebnisse erzielen wie mit einer Standard-PHP-Funktion?

Wir können auch ableiten, dass Sie je nach Ihren Bedürfnissen etwas anderes wählen als jemand anderes:

  • IgBinary ist wirklich nett und performt besser als MsgPack
  • Msgpack komprimiert Ihre Daten besser (beachten Sie, dass ich die Option igbinary compact.string nicht ausprobiert habe).
  • Sie möchten nicht kompilieren? Standards verwenden.

Das war’s, ein weiterer Vergleich der Serialisierungsmethoden, um Ihnen bei der Auswahl zu helfen!

*Getestet mit PHPUnit 3.7.31, PHP 5.5.10 – nur Dekodierung mit einer Standard-Festplatte und alter Dual-Core-CPU – durchschnittliche Zahlen bei 10 gleichen Anwendungsfalltests, Ihre Statistiken könnten unterschiedlich sein

  • Warum nicht das Flag an json_decode übergeben, um die Rückgabe von Arrays zu erzwingen?

    – Alex Jaroschewitsch

    23. November 2014 um 23:51 Uhr


  • Weil es langsam ist. Ich habe das nicht getestet, aber ich denke, dass es schneller ist, einfach die Typänderung von PHP zu erzwingen.

    – Sojuka

    24. November 2014 um 20:59 Uhr

  • Ich weiß nur, dass das Erstellen von Arrays viel schneller ist als Objekte in PHP.

    – Alex Jaroschewitsch

    25. November 2014 um 6:44 Uhr

  • Du sprichst also von json_decode($object, true)im Grunde wird es dasselbe tun wie (array) json_decode($object) aber rekursiv wäre das dasselbe Verhalten und es würde in beiden Fällen erhebliche Kosten verursachen. Beachten Sie, dass ich die Leistungsunterschiede zwischen nicht getestet habe StdClass und array aber darum geht es hier eigentlich nicht.

    – Sojuka

    25. November 2014 um 10:37 Uhr


  • Ich bin mir sicher, dass es weitere Kosten sind, weil es auf einer niedrigeren Ebene ohne Objekte gemacht wird.

    – Alex Jaroschewitsch

    26. November 2014 um 15:00 Uhr

986490cookie-checkBevorzugte Methode zum Speichern von PHP-Arrays (json_encode vs. serialize)

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy