PHP - * быстрый * сериализация / десериализация? - PullRequest
13 голосов
/ 30 марта 2010

У меня есть PHP-скрипт, который создает дерево двоичного поиска поверх довольно большой CSV-файл (5 МБ +). Это хорошо и все, но для чтения / разбора / индексации файла требуется около 3 секунд.

Теперь я подумал, что могу использовать serialize() и unserialize(), чтобы ускорить процесс. Если файл CSV за это время не изменился, нет смысла снова его анализировать.

К моему ужасу, я обнаружил, что вызов serialize() для моего индексного объекта занимает 5 секунд и создает огромный (19 МБ) текстовый файл, тогда как unserialize() занимает непереносимые 27 секунд, чтобы прочитать его обратно. Улучшения выглядят немного иначе. ; -)

Итак, есть ли более быстрый механизм для хранения / восстановления больших графов объектов на / с диска в PHP?

(Чтобы уточнить: я ищу что-то, что занимает значительно меньше, чем вышеупомянутые 3 секунды, чтобы выполнить работу по десериализации.)

Ответы [ 8 ]

8 голосов
/ 30 июля 2010

var_export должно быть намного быстрее, поскольку PHP не нужно будет обрабатывать строку вообще:

// export the process CSV to export.php
$php_array = read_parse_and_index_csv($csv); // takes 3 seconds
$export = var_export($php_array, true);
file_put_contents('export.php', '<?php $php_array = ' . $export . '; ?>');

Затем включите export.php, когда вам это нужно:

include 'export.php';

В зависимости от настроек вашего веб-сервера, вам может потребоваться chmod export.php, чтобы сначала выполнить его.

5 голосов
/ 17 августа 2012

Попробуйте igbinary ... сделал чудеса для меня:

http://pecl.php.net/package/igbinary

4 голосов
/ 24 сентября 2011

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

Преобразование всех IP-адресов в целое или длинное.

Так что, если приходит запрос, вы можете знать, какую часть искать. Для этого есть <?php ip2long() /* and */ long2ip(); функций. Таким образом, от 0 до 2 ^ 32 преобразуют все IP-адреса в 5000K / 50K всего 100 меньших файлов. Такой подход ускоряет сериализацию.

Думай умно, код аккуратно;)

3 голосов
/ 08 апреля 2010

Похоже, что ответ на ваш вопрос - нет.

Даже если вы обнаружите опцию «двоичный формат сериализации», скорее всего, даже это будет замедлять то, что вы предполагаете.

Итак, что вам, возможно, придется использовать (как уже упоминали другие), это база данных, memcached или онлайн-сервис.

Я бы также хотел добавить следующие идеи:

  • кеширование запросов / ответов
  • ваш PHP-скрипт не завершает работу, а становится сетевым сервером для ответа на запросы
  • или, осмелюсь сказать, измените структуру данных и метод запроса, который вы в настоящее время используете
2 голосов
/ 30 марта 2010

здесь я вижу два варианта

сериализация строк, в простейшем виде что-то вроде

  write => implode("\x01", (array) $node);
  read  => explode() + $node->payload = $a[0]; $node->value = $a[1] etc

двоичная сериализация с пакетом ()

  write => pack("fnna*", $node->value, $node->le, $node->ri, $node->payload);
  read  => $node = (object) unpack("fvalue/nre/nli/a*payload", $data);

Было бы интересно сравнить оба варианта и сравнить результаты.

1 голос
/ 30 марта 2010

Если вам нужна скорость, запись или чтение из файловой системы менее чем оптимально.

В большинстве случаев сервер базы данных сможет хранить и извлекать данные гораздо более эффективно, чем скрипт PHP, который читает / записывает файлы.

Другой возможностью будет что-то вроде Memcached .

Сериализация объектов известна не своей производительностью, а простотой использования, и она определенно не подходит для обработки больших объемов данных.

0 голосов
/ 12 июля 2011

Как насчет использования чего-то вроде JSON для формата для хранения / загрузки данных? Я понятия не имею, насколько быстро работает синтаксический анализатор JSON в PHP, но обычно это быстрая операция на большинстве языков и это легкий формат.

http://php.net/manual/en/book.json.php

0 голосов
/ 08 сентября 2010

SQLite поставляется с PHP, вы можете использовать его в качестве базы данных. В противном случае вы можете попробовать использовать сессии, тогда вам не нужно ничего сериализовать, вы просто сохраняете необработанный объект PHP.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...