Preferowana metoda przechowywania tablic PHP (json encode vs serialize)

Muszę przechowywać wielowymiarową tablicę asocjacyjną danych w płaskim pliku do celów buforowania. Od czasu do czasu mogę natknąć się na potrzebę przekonwertowania go do JSON do użytku w mojej aplikacji internetowej, ale zdecydowana większość czasu będę używać tablicy bezpośrednio w PHP.

Czy bardziej efektywne byłoby przechowywanie tablicy jako JSON lub jako tablicy szeregowej PHP w tym pliku tekstowym? Rozglądałem się i wydaje mi się, że w najnowszych wersjach PHP (5.3) json_decode jest faktycznie szybszy niż unserialize.

Obecnie skłaniam się ku przechowywaniu tablicy jako JSON, ponieważ czuję, że jest łatwiejsza do odczytania przez człowieka, jeśli to konieczne, może być używana zarówno w PHP, jak i JavaScript z bardzo małym wysiłkiem, a z tego, co czytałem, może być nawet szybciej dekodować (nie jestem pewien kodowania, choć).

Czy ktoś zna jakieś pułapki? Czy ktoś ma dobre benchmarki, aby pokazać korzyści wydajnościowe każdej z metod?
Author: Jeffrey Bosboom, 2009-04-30

19 answers

Zależy od twoich priorytetów.

Jeśli osiągi są twoją absolutną cechą jazdy, użyj najszybszej. Po prostu upewnij się, że masz pełne zrozumienie różnic, zanim dokonasz wyboru

  • W przeciwieństwie do serialize() musisz dodać dodatkowy parametr, aby znaki UTF-8 pozostały nietknięte: json_encode($array, JSON_UNESCAPED_UNICODE) (w przeciwnym razie Konwertuje znaki UTF-8 na sekwencje escape Unicode).
  • JSON nie będzie miał pamięci jaka była oryginalna Klasa obiektu (są zawsze przywracane jako instancje stdClass).
  • nie możesz wykorzystać __sleep() i __wakeup() z JSON
  • domyślnie tylko właściwości publiczne są serializowane za pomocą JSON. (w PHP>=5.4 możesz zaimplementować JsonSerializable, aby zmienić to zachowanie).
  • JSON jest bardziej przenośny

I jest prawdopodobnie kilka innych różnic, o których nie mogę teraz myśleć.

Prosty test prędkości do porównania dwóch

<?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';
}
 520
Author: Peter Bailey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-16 08:24:17

JSON jest prostszy i szybszy niż format serializacji PHP i powinien być używany , chyba że :

  • przechowujesz głęboko zagnieżdżone tablice: json_decode(): "funkcja ta zwróci false, Jeśli dane zakodowane w JSON są głębsze niż 127 elementów."
  • przechowujesz obiekty, które muszą być niezerializowane jako poprawna Klasa
  • interakcja ze starymi wersjami PHP, które nie obsługują json_decode
 224
Author: Greg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-29 20:13:32

Napisałem blog o tym temacie: "Cache a large array: JSON, serialize or var_export?". W tym poście pokazano, że serialize jest najlepszym wyborem dla małych i dużych tablic. Dla bardzo dużych macierzy (> 70MB) JSON jest lepszym wyborem.

 56
Author: Taco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-02 10:02:48

Możesz być również zainteresowany https://github.com/phadej/igbinary - który zapewnia inny 'silnik' serializacji dla PHP.

Moje losowe / arbitralne "wyniki", używając PHP 5.3.5 na platformie 64bit pokazują:

JSON:

  • JSON zakodowany w 2.180496931076 sekund
  • JSON zdekodowany w 9.8368630409241 sekund
  • serialized "String" size: 13993

Natywne PHP:

  • PHP serialized in 2.9125759601593 seconds
  • PHP w 6.4348418712616 sekund
  • serialized "String" size: 20769

Igbinary:

  • WIN igbinary serialized in 1.6099879741669 seconds
  • WIN igbinrary unserialized in 4.7737920284271 seconds
  • WIN serialized "String" Size: 4467

Tak więc, jest szybciej igbinary_serialize () i igbinary_unserialize() i zużywa mniej miejsca na dysku.

Użyłem fillArray (0, 3) Kod jak wyżej, ale sprawił, że klucze tablicy dłuższe ciągi.

Igbinary może przechowywać te same typy danych, co natywne serialize PHP (więc nie ma problemu z obiektami itp.) i możesz powiedzieć PHP5.3, aby używał go do obsługi sesji, jeśli chcesz.

Zobacz też http://ilia.ws/files/zendcon_2010_hidden_features.pdf - konkretnie slajdy 14/15/16

 50
Author: David Goodwin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-27 18:53:54

Y właśnie testował serialized i JSON koduje i dekoduje, plus rozmiar, który zajmie zapisany ciąg.

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

Możemy wywnioskować, że JSON koduje szybciej i powoduje mniejszy ciąg znaków, ale unserialize jest szybsze do dekodowania łańcucha.

 23
Author: Blunk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-10 23:44:29

Jeśli buforujesz informacje, które ostatecznie chcesz "dołączyć" w późniejszym czasie, możesz spróbować użyć var_export. W ten sposób przyjmujesz tylko hit w "serialize", a nie w "unserialize".

 14
Author: Jordan S. Jones,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-29 23:04:23

Rozszerzyłem test o wydajność unserializacji. Oto liczby, które mam.

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() 

Więc json wydaje się być szybszy w kodowaniu, ale powolny w dekodowaniu. Może więc zależeć od twojej aplikacji i tego, czego oczekujesz najbardziej.

 11
Author: Jeff Whiting,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-23 19:14:59

Wygląda na to, że serialize jest tym, którego użyję z 2 powodów:

  • Ktoś zauważył, że unserialize jest szybsze niż json_decode, a przypadek "read" brzmi bardziej prawdopodobnie niż przypadek "write".

  • Miałem problem z json_encode, gdy miałem Ciągi z nieprawidłowymi znakami UTF-8. Gdy tak się stanie, łańcuch kończy się pusty, powodując utratę informacji.

 8
Author: urraka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-27 00:46:40

Naprawdę fajny temat i po przeczytaniu kilku odpowiedzi, chcę podzielić się moimi eksperymentami na ten temat.

Mam przypadek użycia, w którym jakaś "ogromna" tabela musi być zapytana prawie za każdym razem, gdy rozmawiam z bazą danych(nie pytaj dlaczego, tylko fakt). System buforowania bazy danych nie jest odpowiedni, ponieważ nie będzie buforować różnych żądań, więc pomyślałem o systemach buforowania php.

Próbowałem apcu ale nie pasowało do potrzeb, pamięć nie jest wystarczająco niezawodna w tym przypadku. Następnym krokiem było buforowanie do pliku z serializacją.

Tabela ma 14355 wpisów z 18 kolumnami, to są moje testy i statystyki dotyczące czytania serializowanego cache:

JSON:

Jak wszyscy powiedzieliście, główną niedogodnością z json_encode/json_decode jest to, że przekształca wszystko do StdClass instancji (lub obiektu). Jeśli musisz ją zapętlić, prawdopodobnie zrobisz transformację do tablicy i tak, Zwiększa to czas transformacji

Średni czas: 780.2 ms; zużycie pamięci: 41.5 MB; Pamięć podręczna Rozmiar pliku: 3.8 MB

Msgpack

@hutch msgpack. Ładna stronka. Spróbujmy.

Średni czas: 497 ms; zużycie pamięci: 32MB; Rozmiar pliku cache: 2.8 MB

To jest lepsze, ale wymaga nowego rozszerzenia; kompilowanie czasami boi się ludzi...

IgBinary

@GingerDog igbinary . Zauważ, że ustawiłem igbinary.compact_strings=Off, ponieważ bardziej zależy mi na odczycie wydajności niż Pliku rozmiar.

Średni czas: 411.4 ms; wykorzystanie pamięci: 36.75 MB; Rozmiar pliku cache: 3.3 MB

Lepiej niż msg pack. Ten jednak również wymaga kompilacji.

serialize/unserialize

Średni czas: 477.2 ms; wykorzystanie pamięci: 36.25 MB; Rozmiar pliku cache: 5.9 MB

Lepsze osiągi niż JSON, im większa jest tablica, tym wolniejsza json_decode, ale już to nowość.

Te zewnętrzne rozszerzenia zawężają Rozmiar pliku i wydaje się, że na papier. Liczby nie kłamią*. Jaki jest sens kompilowania rozszerzenia, jeśli uzyskasz prawie takie same wyniki, jak w przypadku standardowej funkcji PHP?

Możemy również wywnioskować, że w zależności od twoich potrzeb, wybierzesz coś innego niż ktoś inny:

  • IgBinary jest naprawdę ładny i działa lepiej niż MsgPack
  • Msgpack jest lepszy w kompresji danych (zauważ, że nie próbowałem igbinary Kompaktowy.opcja string).
  • nie chcesz kompilować? Stosuj standardy.

To jest to, kolejne porównanie metod serializacji, które pomogą Ci wybrać jeden!

*testowane z PHPUnit 3.7.31, php 5.5.10-dekodowanie tylko ze standardowym hardrive i starym dwurdzeniowym procesorem-średnie liczby na 10 tych samych testach przypadków użycia, Twoje statystyki mogą być inne

 7
Author: soyuka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-18 16:46:46

Przetestowałem to bardzo dokładnie na dość złożonym, łagodnie zagnieżdżonym multi-hash ze wszystkimi rodzajami danych (string, NULL, integers) i serialize / unserialize skończyło się znacznie szybciej niż json_encode/json_decode.

Jedyną zaletą json w moich testach było to, że jest mniejszy "spakowany" rozmiar.

Są one wykonane pod PHP 5.3.3, daj mi znać, jeśli chcesz więcej szczegółów.

Oto wyniki testów, a następnie kod do ich wytworzenia. Nie mogę podać danych testowych, ponieważ ujawniłyby informacje, których nie mogę wypuścić na wolność.

JSON encoded in 2.23700618744 seconds
PHP serialized in 1.3434419632 seconds
JSON decoded in 4.0405561924 seconds
PHP unserialized in 1.39393305779 seconds

serialized size : 14549
json_encode size : 11520
serialize() was roughly 66.51% faster than json_encode()
unserialize() was roughly 189.87% faster than json_decode()
json_encode() string was roughly 26.29% smaller than serialize()

//  Time json encoding
$start = microtime( true );
for($i = 0; $i < 10000; $i++) {
    json_encode( $test );
}
$jsonTime = microtime( true ) - $start;
echo "JSON encoded in $jsonTime seconds<br>";

//  Time serialization
$start = microtime( true );
for($i = 0; $i < 10000; $i++) {
    serialize( $test );
}
$serializeTime = microtime( true ) - $start;
echo "PHP serialized in $serializeTime seconds<br>";

//  Time json decoding
$test2 = json_encode( $test );
$start = microtime( true );
for($i = 0; $i < 10000; $i++) {
    json_decode( $test2 );
}
$jsonDecodeTime = microtime( true ) - $start;
echo "JSON decoded in $jsonDecodeTime seconds<br>";

//  Time deserialization
$test2 = serialize( $test );
$start = microtime( true );
for($i = 0; $i < 10000; $i++) {
    unserialize( $test2 );
}
$unserializeTime = microtime( true ) - $start;
echo "PHP unserialized in $unserializeTime seconds<br>";

$jsonSize = strlen(json_encode( $test ));
$phpSize = strlen(serialize( $test ));

echo "<p>serialized size : " . strlen(serialize( $test )) . "<br>";
echo "json_encode size : " . strlen(json_encode( $test )) . "<br></p>";

//  Compare them
if ( $jsonTime < $serializeTime )
{
    echo "json_encode() was roughly " . number_format( ($serializeTime / $jsonTime - 1 ) * 100, 2 ) . "% faster than serialize()";
}
else if ( $serializeTime < $jsonTime )
{
    echo "serialize() was roughly " . number_format( ($jsonTime / $serializeTime - 1 ) * 100, 2 ) . "% faster than json_encode()";
} else {
    echo 'Unpossible!';
}
    echo '<BR>';

//  Compare them
if ( $jsonDecodeTime < $unserializeTime )
{
    echo "json_decode() was roughly " . number_format( ($unserializeTime / $jsonDecodeTime - 1 ) * 100, 2 ) . "% faster than unserialize()";
}
else if ( $unserializeTime < $jsonDecodeTime )
{
    echo "unserialize() was roughly " . number_format( ($jsonDecodeTime / $unserializeTime - 1 ) * 100, 2 ) . "% faster than json_decode()";
} else {
    echo 'Unpossible!';
}
    echo '<BR>';
//  Compare them
if ( $jsonSize < $phpSize )
{
    echo "json_encode() string was roughly " . number_format( ($phpSize / $jsonSize - 1 ) * 100, 2 ) . "% smaller than serialize()";
}
else if ( $phpSize < $jsonSize )
{
    echo "serialize() string was roughly " . number_format( ($jsonSize / $phpSize - 1 ) * 100, 2 ) . "% smaller than json_encode()";
} else {
    echo 'Unpossible!';
}
 6
Author: Mr. Sox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-17 00:14:31

Zrobiłem mały benchmark, jak również. Moje wyniki były takie same. Ale potrzebuję wydajności dekodowania. Gdzie zauważyłem, jak kilka osób powyżej również powiedział, {[0] } jest szybszy niż json_decode. unserialize zajmuje około 60-70% czasu json_decode. Więc wniosek jest dość prosty: Gdy potrzebujesz wydajności w kodowaniu, użyj json_encode, Gdy potrzebujesz wydajności podczas dekodowania, użyj unserialize. Ponieważ nie możesz połączyć dwóch funkcji, musisz dokonać wyboru tam, gdzie potrzebujesz większej wydajności.

Mój benchmark w pseudo:

  • Zdefiniuj tablicę $arr z kilkoma losowymi kluczami i wartościami
  • for x
  • for y
  • dla y
  • echo wyniku, który był szybszy

Na avarage: unserialize wygrał 96 razy ponad 4 razy kod json_decode. Z avarage około 1.5 ms Ponad 2.5 ms.

 5
Author: Jelmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-12 10:18:39

Zanim podejmiesz ostateczną decyzję, pamiętaj, że format JSON nie jest bezpieczny dla tablic asocjacyjnych- json_decode() zwróci je jako obiekty:

$config = array(
    'Frodo'   => 'hobbit',
    'Gimli'   => 'dwarf',
    'Gandalf' => 'wizard',
    );
print_r($config);
print_r(json_decode(json_encode($config)));

Wyjście To:

Array
(
    [Frodo] => hobbit
    [Gimli] => dwarf
    [Gandalf] => wizard
)
stdClass Object
(
    [Frodo] => hobbit
    [Gimli] => dwarf
    [Gandalf] => wizard
)
 2
Author: too much php,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-21 03:34:54

Tak dla twojej wiadomości -- Jeśli chcesz serializować swoje dane do czegoś łatwego do odczytania i zrozumienia, takiego jak JSON, ale z większą kompresją i wyższą wydajnością, powinieneś sprawdzić messagepack.

 1
Author: Hutch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-12 12:40:22

Sprawdź Wyniki tutaj (przepraszam za włamanie umieszczenie kodu PHP w polu kodu JS):

Http://jsfiddle.net/newms87/h3b0a0ha/embedded/result/

Wyniki: serialize() i unserialize() są znacznie szybsze w PHP 5.4 na tablicach o różnej wielkości.

Zrobiłem skrypt testowy na rzeczywistych danych do porównania json_encode vs serialize i json_decode vs unserialize. Test został uruchomiony na systemie buforowania w produkcji witryny e-commerce. To po prostu pobiera dane już w pamięci podręcznej i testuje czasy kodowania / dekodowania (lub serializacji / unserializacji) wszystkich danych i umieszczam je w łatwej do zobaczenia tabeli.

Uruchomiłem to na serwerze PHP 5.4 shared hosting.

Wyniki były bardzo rozstrzygające, że dla tych dużych i małych zestawów danych serialize i unserialize były wyraźnymi zwycięzcami. W szczególności dla mojego przypadku użycia, json_decode i unserialize są najważniejsze dla systemu buforowania. Unserialize było niemal wszechobecne zwycięzca. Zwykle był 2 do 4 razy (czasami 6 lub 7 razy) tak szybki jak json_decode.

Warto zauważyć różnicę w wynikach z @ peter-bailey.

Oto kod PHP użyty do wygenerowania wyników:

<?php

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

function _count_depth($array)
{
    $count     = 0;
    $max_depth = 0;
    foreach ($array as $a) {
        if (is_array($a)) {
            list($cnt, $depth) = _count_depth($a);
            $count += $cnt;
            $max_depth = max($max_depth, $depth);
        } else {
            $count++;
        }
    }

    return array(
        $count,
        $max_depth + 1,
    );
}

function run_test($file)
{
    $memory     = memory_get_usage();
    $test_array = unserialize(file_get_contents($file));
    $memory     = round((memory_get_usage() - $memory) / 1024, 2);

    if (empty($test_array) || !is_array($test_array)) {
        return;
    }

    list($count, $depth) = _count_depth($test_array);

    //JSON encode test
    $start            = microtime(true);
    $json_encoded     = json_encode($test_array);
    $json_encode_time = microtime(true) - $start;

    //JSON decode test
    $start = microtime(true);
    json_decode($json_encoded);
    $json_decode_time = microtime(true) - $start;

    //serialize test
    $start          = microtime(true);
    $serialized     = serialize($test_array);
    $serialize_time = microtime(true) - $start;

    //unserialize test
    $start = microtime(true);
    unserialize($serialized);
    $unserialize_time = microtime(true) - $start;

    return array(
        'Name'                   => basename($file),
        'json_encode() Time (s)' => $json_encode_time,
        'json_decode() Time (s)' => $json_decode_time,
        'serialize() Time (s)'   => $serialize_time,
        'unserialize() Time (s)' => $unserialize_time,
        'Elements'               => $count,
        'Memory (KB)'            => $memory,
        'Max Depth'              => $depth,
        'json_encode() Win'      => ($json_encode_time > 0 && $json_encode_time < $serialize_time) ? number_format(($serialize_time / $json_encode_time - 1) * 100, 2) : '',
        'serialize() Win'        => ($serialize_time > 0 && $serialize_time < $json_encode_time) ? number_format(($json_encode_time / $serialize_time - 1) * 100, 2) : '',
        'json_decode() Win'      => ($json_decode_time > 0 && $json_decode_time < $serialize_time) ? number_format(($serialize_time / $json_decode_time - 1) * 100, 2) : '',
        'unserialize() Win'      => ($unserialize_time > 0 && $unserialize_time < $json_decode_time) ? number_format(($json_decode_time / $unserialize_time - 1) * 100, 2) : '',
    );
}

$files = glob(dirname(__FILE__) . '/system/cache/*');

$data = array();

foreach ($files as $file) {
    if (is_file($file)) {
        $result = run_test($file);

        if ($result) {
            $data[] = $result;
        }
    }
}

uasort($data, function ($a, $b) {
    return $a['Memory (KB)'] < $b['Memory (KB)'];
});

$fields = array_keys($data[0]);
?>

<table>
    <thead>
    <tr>
        <?php foreach ($fields as $f) { ?>
            <td style="text-align: center; border:1px solid black;padding: 4px 8px;font-weight:bold;font-size:1.1em"><?= $f; ?></td>
        <?php } ?>
    </tr>
    </thead>

    <tbody>
    <?php foreach ($data as $d) { ?>
        <tr>
            <?php foreach ($d as $key => $value) { ?>
                <?php $is_win = strpos($key, 'Win'); ?>
                <?php $color = ($is_win && $value) ? 'color: green;font-weight:bold;' : ''; ?>
                <td style="text-align: center; vertical-align: middle; padding: 3px 6px; border: 1px solid gray; <?= $color; ?>"><?= $value . (($is_win && $value) ? '%' : ''); ?></td>
            <?php } ?>
        </tr>
    <?php } ?>
    </tbody>
</table>
 1
Author: newms87,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-20 21:46:45

Najpierw zmieniłem skrypt, aby zrobić więcej benchmarkingu (a także zrobić 1000 uruchomień zamiast tylko 1):

<?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);

$totalJsonTime = 0;
$totalSerializeTime = 0;
$totalJsonWins = 0;

for ($i = 0; $i < 1000; $i++) {
    // Time json encoding
    $start = microtime(true);
    $json = json_encode($testArray);
    $jsonTime = microtime(true) - $start;
    $totalJsonTime += $jsonTime;

    // Time serialization
    $start = microtime(true);
    $serial = serialize($testArray);
    $serializeTime = microtime(true) - $start;
    $totalSerializeTime += $serializeTime;

    if ($jsonTime < $serializeTime) {
        $totalJsonWins++;
    }
}

$totalSerializeWins = 1000 - $totalJsonWins;

// Compare them
if ($totalJsonTime < $totalSerializeTime) {
    printf("json_encode() (wins: $totalJsonWins) was roughly %01.2f%% faster than serialize()\n", ($totalSerializeTime / $totalJsonTime - 1) * 100);
} else {
    printf("serialize() (wins: $totalSerializeWins) was roughly %01.2f%% faster than json_encode()\n", ($totalJsonTime / $totalSerializeTime - 1) * 100);
}

$totalJsonTime = 0;
$totalJson2Time = 0;
$totalSerializeTime = 0;
$totalJsonWins = 0;

for ($i = 0; $i < 1000; $i++) {
    // Time json decoding
    $start = microtime(true);
    $orig = json_decode($json, true);
    $jsonTime = microtime(true) - $start;
    $totalJsonTime += $jsonTime;

    $start = microtime(true);
    $origObj = json_decode($json);
    $jsonTime2 = microtime(true) - $start;
    $totalJson2Time += $jsonTime2;

    // Time serialization
    $start = microtime(true);
    $unserial = unserialize($serial);
    $serializeTime = microtime(true) - $start;
    $totalSerializeTime += $serializeTime;

    if ($jsonTime < $serializeTime) {
        $totalJsonWins++;
    }
}

$totalSerializeWins = 1000 - $totalJsonWins;


// Compare them
if ($totalJsonTime < $totalSerializeTime) {
    printf("json_decode() was roughly %01.2f%% faster than unserialize()\n", ($totalSerializeTime / $totalJsonTime - 1) * 100);
} else {
    printf("unserialize() (wins: $totalSerializeWins) was roughly %01.2f%% faster than json_decode()\n", ($totalJsonTime / $totalSerializeTime - 1) * 100);
}

// Compare them
if ($totalJson2Time < $totalSerializeTime) {
    printf("json_decode() was roughly %01.2f%% faster than unserialize()\n", ($totalSerializeTime / $totalJson2Time - 1) * 100);
} else {
    printf("unserialize() (wins: $totalSerializeWins) was roughly %01.2f%% faster than array json_decode()\n", ($totalJson2Time / $totalSerializeTime - 1) * 100);
}

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';
}

Użyłem tej kompilacji PHP 7:

[[1]}PHP 7.0.14 (cli) (zbudowany: 18 stycznia 2017 19: 13: 23) (NTS) Copyright (c) 1997-2016 Grupa PHP Zend Engine v3. 0. 0, Copyright (c) 1998-2016 Zend Technologies Zend OPcache v7.0.14, Copyright (c) 1999-2016, by Zend Technologies

A moje wyniki były:

Serialize () (wygranych: 999) było Około 10.98% szybciej niż json_encode() unserialize () (wygranych: 987) było o około 33.26% szybsze niż json_decode() unserialize () (wygranych: 987) był o około 48.35% szybszy od array json_decode ()

Więc najwyraźniej , serialize/unserialize jest najszybszą metodą, podczas gdy json_encode/decode jest najbardziej przenośną.

Jeśli rozważysz scenariusz, w którym odczytywasz / zapisujesz dane serializowane 10x lub częściej niż musisz wysyłać lub odbierać dane spoza PHP system, nadal lepiej jest użyć serialize / unserialize i mieć json_encode lub json_decode przed serializacją pod względem czasu.

 1
Author: Shawn Tolidano,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-05 04:37:58

JSON jest lepszy, jeśli chcesz wykonać kopię zapasową danych i przywrócić je na innym komputerze lub przez FTP.

Na przykład z serialize jeśli przechowujesz dane na serwerze Windows, pobierz je przez FTP i przywróć na Linuksie, który nie może już działać z powodu ponownego kodowania charachter, ponieważ serialize przechowuje długość łańcuchów, a w transkodowaniu Unicode > UTF-8 około 1 bajt charachter może stać się 2 bajtami, co powoduje awarię algorytmu.

 0
Author: Informate.it,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-26 10:31:43

THX-dla tego kodu odniesienia:

Moje wyniki na tablicy używam do konfiguracji są jako fallows: JSON zakodowany w 0.0031511783599854 sekund
PHP wygenerowano w 0.0037961006164551 sekund
json_encode() był o około 20.47% szybszy niż serialize() JSON zakodowany w 0.0070841312408447 sekund
PHP wygenerowano w 0.0035839080810547 sekund
unserialize() był o około 97,66% szybszy niż json_encode()

Więc - przetestuj to na własnych danych.

 0
Author: mk182,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-10 12:10:04

Jeśli podsumować to, co ludzie tutaj mówią, json_decode / encode wydaje się szybszy niż serialize / unserialize, ale Jeśli wykonasz var_dump, typ obiektu serializowanego zostanie zmieniony. Jeśli z jakiegoś powodu chcesz zachować Typ, przejdź z serialize!

(Spróbuj na przykład stdClass vs array)

Serialize/unserialize:

Array cache:
array (size=2)
  'a' => string '1' (length=1)
  'b' => int 2
Object cache:
object(stdClass)[8]
  public 'field1' => int 123
This cache:
object(Controller\Test)[8]
  protected 'view' => 

Json encode / decode

Array cache:
object(stdClass)[7]
  public 'a' => string '1' (length=1)
  public 'b' => int 2
Object cache:
object(stdClass)[8]
  public 'field1' => int 123
This cache:
object(stdClass)[8]

Jak widać json_encode / decode konwertuje wszystkie na stdClass, co nie jest tak dobre, informacja o obiekcie została utracona... Więc zdecyduj na podstawie potrzeb, zwłaszcza jeśli chodzi nie tylko o tablice...

 0
Author: David Constantine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-30 19:51:27

Sugerowałbym użycie Super Cache, czyli mechanizmu Cache plików, który nie będzie używał json_encode ani serialize. Jest prosty w obsłudze i bardzo szybki w porównaniu do innych mechanizmów pamięci podręcznej PHP.

Https://packagist.org/packages/smart-php/super-cache

Ex:

<?php
require __DIR__.'/vendor/autoload.php';
use SuperCache\SuperCache as sCache;

//Saving cache value with a key
// sCache::cache('<key>')->set('<value>');
sCache::cache('myKey')->set('Key_value');

//Retrieving cache value with a key
echo sCache::cache('myKey')->get();
?>
 0
Author: shabeer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-19 08:10:47