Предпочтительный метод хранения массивов PHP (json_encode vs serialize)

524

Мне нужно сохранить многомерный ассоциативный массив данных в плоском файле для целей кеширования. Иногда мне приходилось переходить на JSON для использования в моем веб-приложении, но в большинстве случаев я буду использовать массив непосредственно в PHP.

Будет ли более эффективным хранить массив как JSON или как сериализованный массив PHP в этом текстовом файле? Я огляделся, и кажется, что в новейших версиях PHP (5.3) json_decode на самом деле быстрее, чем unserialize.

В настоящее время я склоняюсь к тому, чтобы хранить массив как JSON, поскольку я чувствую, что его легче читать человеком, если это необходимо, его можно использовать как в PHP, так и в JavaScript с очень небольшим усилием и из того, что я прочитал, может даже быть быстрее для декодирования (не уверен в кодировке, хотя).

Кто-нибудь знает какие-нибудь подводные камни? У кого-нибудь есть хорошие ориентиры, чтобы показать преимущества производительности любого из методов?

Теги:
arrays
performance
serialization

18 ответов

512
Лучший ответ

Зависит от ваших приоритетов.

Если производительность является вашей абсолютной характеристикой вождения, то, во что бы то ни стало, используйте самую быструю. Просто убедитесь, что у вас есть полное понимание различий, прежде чем сделать выбор.

  • По умолчанию json_encode() преобразует символы UTF-8 в escape-последовательности Unicode, а serialize() - нет. Примечание.. Чтобы оставить символы UTF-8 нетронутыми, вы можете использовать опцию JSON_UNESCAPED_UNICODE с PHP 5.4.
  • JSON не будет иметь памяти о том, что был исходным классом объекта (они всегда восстанавливаются как экземпляры stdClass).
  • Вы не можете использовать __sleep() и __wakeup() с помощью JSON
  • Только публичные свойства сериализуются с помощью JSON. Примечание.. С PHP 5.4 вы можете реализовать JsonSerializable, чтобы изменить это поведение.
  • JSON более портативен.

И, вероятно, есть несколько других различий, о которых я не могу сейчас думать.

Простой тест скорости для сравнения двух

<?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';
}
  • 0
    Вы делаете некоторые важные моменты. К счастью, для моего случая я храню простые массивы (других массивов, целых, bools и строк) без объектов. Если бы я хранил объекты, IMO, сериализация была бы способом пойти.
  • 1
    Жаль, что json_encode / json_decode - это php 5.2 и выше. disgusts_uncover_akin_umbriel
Показать ещё 12 комментариев
211

JSON проще и быстрее, чем формат сериализации PHP, и его следует использовать , если:

  • Вы храните глубоко вложенные массивы: json_decode(): "Эта функция вернет false, если закодированные данные JSON глубже 127 элементов".
  • Вы сохраняете объекты, которые должны быть неэтериализованы как правильный класс
  • Вы взаимодействуете со старыми версиями PHP, которые не поддерживают json_decode
  • 10
    Отличный ответ. Ха-ха, 127 уровней глубоко, кажется немного безумным; к счастью, я собираюсь только как 2-3 максимум. Есть ли у вас какие-либо данные, подтверждающие тот факт, что json_decode / json_encode работает быстрее, чем десериализация / сериализация?
  • 1
    Я проверял это некоторое время назад, и json вышел быстрее - у меня больше нет данных.
Показать ещё 4 комментария
55

Я написал блогпост об этой теме: " Кэш большого массива: JSON, serialize или var_export?". В этом сообщении показано, что сериализация является лучшим выбором для массивов малых и больших размеров. Для очень больших массивов ( > 70 МБ) лучше выбрать JSON.

  • 4
    Ссылка больше не доступна.
  • 1
    Спасибо, лось, я обновил ссылку. Хотя этой статье уже почти 6 лет, и она может быть не такой точной для текущих версий PHP.
Показать ещё 5 комментариев
42

Вы также можете быть заинтересованы в https://github.com/phadej/igbinary - который предоставляет другой механизм сериализации для PHP.

Мои случайные/произвольные показатели производительности, использующие PHP 5.3.5 на 64-битной платформе, показывают:

JSON:

  • JSON, закодированный в 2.180496931076 секунд
  • JSON декодируется в 9.8368630409241 секундах
  • сериализованный размер "String" : 13993

Нативный PHP:

  • PHP сериализован в 2.9125759601593 секундах
  • PHP несертифицирован в 6.4348418712616 секундах
  • сериализованный размер "String" : 20769

Igbinary:

  • WIN igbinary сериализован в 1.6099879741669 секунд
  • WIN igbinrary unserialized в 4.7737920284271 секундах
  • WIN сериализован "String" Размер: 4467

Итак, это быстрее для igbinary_serialize() и igbinary_unserialize() и использует меньше дискового пространства.

Я использовал код fillArray (0, 3), как указано выше, но сделал ключи массива более длинными.

igbinary может хранить те же типы данных, что и PHP native serialize (так что не проблема с объектами и т.д.), и вы можете сказать PHP5.3 использовать его для обработки сеанса, если вы этого пожелаете.

См. также http://ilia.ws/files/zendcon_2010_hidden_features.pdf - в частности слайды 14/15/16

22

Y просто проверял сериализованный и json-кодирование и декодирование, а также размер, на который будет храниться строка.

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

Мы можем заключить, что JSON быстрее кодирует и выводит меньшую строку, но unserialize быстрее декодирует строку.

  • 6
    Я не знаю, почему люди всегда делают тест производительности с таким маленьким набором данных. При этом у вас есть все накладные расходы, которые добавляют ошибки к вашим результатам. И если люди заинтересованы в производительности, это, вероятно, потому, что у них очень большой набор данных, потому что нет смысла набирать микросекунду один раз.
  • 1
    Довольно часто я перебираю множество небольших наборов данных. С сотнями небольших наборов данных получение 1 мс для каждого все еще интересно.
Показать ещё 1 комментарий
14

Если вы кешируете информацию, которую вы в конечном итоге захотите "включить" в более поздний момент времени, вы можете попробовать использовать var_export. Таким образом, вы принимаете удар только в "сериализации", а не в "unserialize".

  • 0
    Скорее всего, это самый быстрый способ. Я написал пример для SO «PHP - быстрая сериализация / десериализация»: stackoverflow.com/questions/2545455/…
11

Я добавил тест, чтобы включить производительность несериализации. Вот цифры, которые я получил.

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, кажется, быстрее для кодирования, но медленный в декодировании. Таким образом, это может зависеть от вашего приложения и того, что вы ожидаете делать больше всего.

8

Кажется, что сериализация - это тот, который я буду использовать по двум причинам:

  • Кто-то отметил, что unserialize быстрее, чем json_decode, и случай с "чтением" звучит более вероятным, чем "запись".

  • У меня были проблемы с json_encode при наличии строк с недопустимыми символами UTF-8. Когда это происходит, строка заканчивается пустым, что приводит к потере информации.

6

Действительно хорошая тема, и, прочитав несколько ответов, я хочу поделиться своими экспериментами по этому вопросу.

У меня есть прецедент, когда некоторая "огромная" таблица должна запрашиваться почти каждый раз, когда я разговариваю с базой данных (не спрашивайте, почему, просто факт). Система кэширования базы данных не подходит, поскольку она не будет кэшировать разные запросы, поэтому я, хотя, о системах кэширования php.

Я пробовал apcu, но он не соответствовал потребностям, в этом случае память недостаточно надежна. Следующим шагом было кэширование в файл с сериализацией.

Таблица содержит 14355 записей с 18 столбцами, это мои тесты и статистика при чтении сериализованного кеша:

JSON:

Как вы все сказали, основным неудобством с json_encode/json_decode является то, что он преобразует все в экземпляр StdClass (или Object). Если вам нужно зацикливать его, преобразование его в массив - это то, что вы, вероятно, сделаете, и да, это увеличивает время преобразования

среднее время: 780,2 мс; использование памяти: 41,5 МБ; размер кеш файла: 3,8 МБ

Msgpack

@hutch упоминает msgpack. Довольно сайт. Попробуем попробовать?

среднее время: 497 мс; использование памяти: 32 МБ; размер кеш файла: 2,8 МБ

Это лучше, но требует нового расширения; компиляция иногда боится людей...

IgBinary

@GingerDog упоминает igbinary. Обратите внимание, что я установил igbinary.compact_strings=Off, потому что мне больше нравится чтение результатов, чем размер файла.

среднее время: 411,4 мс; использование памяти: 36,75 МБ; размер кеш файла: 3,3 МБ

Лучше, чем пакет msg. Тем не менее, это требует компиляции тоже.

serialize/<Т26 >

среднее время: 477,2 мс; использование памяти: 36,25 МБ; размер кеш файла: 5.9MB

Чем выше производительность, чем JSON, тем больше массив, медленнее json_decode, но вы уже новичок в этом.

Эти внешние расширения сужают размер файла и выглядят великолепно на бумаге. Числа не лежат *. Какой смысл компилировать расширение, если вы получите почти те же результаты, что и у стандартной функции PHP?

Мы также можем вывести, что в зависимости от ваших потребностей вы выберете что-то другое, чем кто-либо другой:

  • IgBinary действительно хорош и работает лучше, чем MsgPack
  • Msgpack лучше сжимает ваши данные (обратите внимание, что я не пробовал igbinary compact.string).
  • Не хотите компилировать? Использовать стандарты.

Чтобы это, другое сравнение методов сериализации поможет вам выбрать один!

* Протестировано с помощью PHPUnit 3.7.31, php 5.5.10 - только декодирование со стандартным жестким диском и старым двухъядерным процессором - среднее число на 10 одинаковых тестах использования, ваша статистика может отличаться

  • 0
    Почему бы не передать флаг json_decode для принудительного возвращения массивов?
  • 0
    Потому что это медленно. Я не проверял это, но я думаю, что просто заставить изменение типа с php быстрее.
Показать ещё 3 комментария
6

Я очень тщательно протестировал это на довольно сложном, мягко вложенном мульти-хеше со всеми видами данных в нем (string, NULL, integers), а serialize/unserialize оказался намного быстрее, чем json_encode/json_decode.

Единственное преимущество, которое у json в моих тестах было в меньшем "упакованном" размере.

Это делается в PHP 5.3.3, дайте мне знать, если вы хотите получить более подробную информацию.

Вот результаты тестов, затем код для их создания. Я не могу предоставить тестовые данные, так как он будет раскрывать информацию, которую я не могу выпустить в дикой природе.

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!';
}
  • 0
    Я только что выполнил аналогичный тест с PHP 5.4.12 и нашел похожие результаты: {un,} сериализация происходит быстрее. Мои данные - это хэши, вложенные в 3 уровня (900k сериализовано).
5

Я сделал небольшой ориентир. Мои результаты были одинаковыми. Но мне нужна производительность декодирования. Там, где я заметил, как и несколько человек выше, unserialize быстрее, чем json_decode. unserialize занимает примерно 60-70% времени json_decode. Таким образом, вывод довольно прост: Если вам нужна производительность в кодировке, используйте json_encode, когда вам требуется производительность при декодировании, используйте unserialize. Поскольку вы не можете объединить две функции, вам нужно сделать выбор, где вам нужно больше производительности.

Мой тест в псевдо:

  • Определить массив $arr несколькими случайными ключами и значениями
  • для x < 100; х ++; serialize и json_encode array_rand $arr
  • для y < 1000; у ++; json_decode json закодированная строка - время вычисления
  • для y < 1000; у ++; unserialize сериализованная строка - время вычисления
  • повторить результат, который был быстрее

В avarage: unserialize выиграл 96 раз в 4 раза json_decode. С пропускной способностью примерно 1,5 мс за 2,5 мс.

2

Прежде чем принимать окончательное решение, имейте в виду, что формат JSON небезопасен для ассоциативных массивов - json_decode() вернет их вместо объектов:

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

Выход:

Array
(
    [Frodo] => hobbit
    [Gimli] => dwarf
    [Gandalf] => wizard
)
stdClass Object
(
    [Frodo] => hobbit
    [Gimli] => dwarf
    [Gandalf] => wizard
)
  • 0
    Действительно, ты прав. Я имею в виду, это объекты JavaScript Afterall! К счастью, если вы знаете, что то, что вы кодировали с помощью json_encode было ассоциативным массивом, вы можете легко принудительно вернуть его обратно в массив следующим образом: $json = json_encode($some_assoc_array); $back_to_array = (array)json_decode($json); Также хорошо отметить, что вы можете обращаться к объектам так же, как к массивам в PHP, поэтому в типичном сценарии вы даже не почувствуете разницу. Хороший момент, хотя!
  • 30
    @toomuchphp, извините, но вы не правы. Существует второй параметр для json_decode 'bool $ assoc = false', который заставляет json_decode создавать массив. @KyleFarris, это также должно быть быстрее, чем использование Typecast для массива.
Показать ещё 3 комментария
1

Посмотрите результаты здесь (извините за взломать PHP-код в поле кода JS):

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

РЕЗУЛЬТАТЫ: serialize() и unserialize() являются значительно более быстрыми в PHP 5.4 на массивах разного размера.

Я сделал тест script для данных реального мира для сравнения json_encode vs serialize и json_decode vs unserialize. Тест проводился на системе кэширования на веб-сайте электронной коммерции. Он просто берет данные уже в кеше и проверяет время для кодирования/декодирования (или сериализации/несериализации) всех данных, и я помещаю его в удобную для просмотра таблицу.

Я запустил это на сервере хостинга PHP 5.4.

Результаты были очень убедительными, что для этих больших и малых наборов данных сериализация и неэтериализация были явными победителями. В частности, для моего варианта использования json_decode и unserialize являются наиболее важными для системы кэширования. Unserialize был почти повсеместным победителем здесь. Это было обычно от 2 до 4 раз (иногда 6 или 7 раз) так же быстро, как json_decode.

Интересно отметить разницу в результатах от @peter-bailey.

Вот код PHP, используемый для генерации результатов:

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

просто fyi - если вы хотите сериализовать свои данные на что-то легкое для чтения и понимания, как JSON, но с большим сжатием и более высокой производительностью, вы должны проверить messagepack.

  • 2
    если это просто к вашему сведению, то лучше оставить комментарий.
0

Если суммировать то, что говорят здесь люди, json_decode/encode кажется быстрее, чем serialize/unserialize НО Если вы выберете var_dump, тип сериализованного объекта будет изменен. Если по какой-то причине вы хотите сохранить тип, перейдите к сериализации!

(попробуйте, например, stdClass vs array)

сериализации/десериализации:

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]

Как вы видите, json_encode/decode преобразует все в stdClass, что не так хорошо, информация об объекте потеряна... Поэтому решайте на основе потребностей, особенно если это не только массивы...

  • 0
    Просто примечание: в большинстве других ответов говорится, что сериализация / десериализация происходит быстрее.
0

Во-первых, я изменил script, чтобы выполнить еще один бенчмаркинг (а также сделать 1000 запусков вместо 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';
}

Я использовал эту сборку PHP 7:

PHP 7.0.14 (cli) (построено: 18 января 2017 19:13:23) (NTS) Copyright (c) 1997-2016 PHP Group Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies     с Zend OPcache v7.0.14, Copyright (c) 1999-2016, Zend Technologies

И мои результаты:

serialize() (побед: 999) был примерно на 10,98% быстрее, чем json_encode() unserialize() (побед: 987) был примерно на 33,26% быстрее, чем json_decode() unserialize() (побед: 987) был примерно на 48,35% быстрее, чем массив json_decode()

Значит ясно, serialize/unserialize является самым быстрым методом, а json_encode/decode является наиболее переносимым.

Если вы рассматриваете сценарий, в котором вы читаете/записываете сериализованные данные 10x или чаще, чем вам нужно отправлять или получать из системы, отличной от PHP, вы STILL лучше использовать serialize/unserialize и иметь json_encode или json_decode до сериализации с точки зрения времени.

0

JSON лучше, если вы хотите сделать резервную копию данных и восстановить их на другом компьютере или через FTP.

Например, с сериализацией, если вы храните данные на сервере Windows, загрузите его через FTP и восстановите его на Linux, который больше не может работать из-за повторного кодирования charachter, поскольку сериализация сохраняет длину строк и в перекодировке Unicode > UTF-8, 1 байт-хакер может стать 2 байтами, что приведет к сбою алгоритма.

0

спасибо - для этого эталонного кода:

Мои результаты по массиву, который я использую для конфигурации, являются парой: JSON закодирован в 0,0031511783599854 секунд
PHP сериализуется в 0,0037961006164551 секунд
json_encode() был примерно на 20,47% быстрее, чем serialize() JSON закодирован в 0,0070841312408447 секунд
PHP сериализуется в 0,0035839080810547 секунд
unserialize() был примерно на 97,66% быстрее, чем json_encode()

Итак, проверьте его на свои собственные данные.

  • 0
    Вы имеете в виду, что json_decode () в "unserialize () был примерно на 97,66% быстрее, чем json_encode ()", да?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню