PHP - * быстрый * serialize/unserialize?
У меня есть PHP script, который создает дерево двоичное дерево поиска над довольно большой CSV файл (5MB +). Это хорошо и все, но для чтения/разбора/индексации файла требуется около 3 секунд.
Теперь я подумал, что могу использовать serialize()
и unserialize()
, чтобы ускорить процесс. Когда CSV файл не изменился в то же время, нет смысла разбирать его снова.
К моему ужасу я нахожу, что вызов serialize()
на моем индексном объекте занимает 5 секунд и создает огромный (19 МБ) текстовый файл, тогда как unserialize()
занимает 27 секунд, чтобы прочитать его. Улучшения выглядят несколько иначе.; -)
Итак, есть ли более быстрый механизм для хранения/восстановления графов больших объектов на/с диска в PHP?
(Чтобы уточнить: я ищу что-то, что занимает значительно меньше, чем вышеупомянутые 3 секунды, чтобы выполнить задание де-сериализации.)
Ответы
Ответ 1
Кажется, что ответ на ваш вопрос - нет.
Даже если вы обнаружите вариант "двоичного формата сериализации", скорее всего, даже это будет замедлять то, что вы предполагаете.
Итак, что вам, возможно, придется искать в использовании (как упоминалось выше), это база данных, memcached или онлайн-сервис.
Я хотел бы добавить следующие идеи:
- кэширование запросов/ответов
- ваш PHP script не завершает работу, а становится сетевым сервером для ответа на запросы
- или, смею сказать, изменить структуру данных и метод запроса, который вы используете в настоящее время.
Ответ 2
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, чтобы сделать его выполнимым.
Ответ 3
Попробуйте igbinary... сделал чудеса для меня:
http://pecl.php.net/package/igbinary
Ответ 4
Сначала вам нужно изменить способ работы вашей программы. разделите CSV файл на более мелкие куски. Я полагаю, это IP-хранилище данных.,
Преобразование всех IP-адресов в целые или длинные.
Итак, если запрос приходит, вы можете узнать, какую часть смотреть.
Для этого существуют функции <?php ip2long() /* and */ long2ip();
.
Таким образом, от 0 до 2 ^ 32 конвертировать все IP-адреса в 5000K/50K всего 100 файлов меньшего размера.
Этот подход ускоряет сериализацию.
Думайте умный, код аккуратно;)
Ответ 5
Здесь я вижу два варианта.
сериализация строк, в простейшей форме что-то вроде
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);
Было бы интересно проверить оба варианта и сравнить результаты.
Ответ 6
Если вам нужна скорость, запись или чтение из файловой системы менее чем оптимально.
В большинстве случаев сервер базы данных сможет хранить и извлекать данные гораздо эффективнее, чем PHP script, который является чтением/записью файлов.
Другая возможность - это что-то вроде Memcached.
Сериализация объектов не известна своей производительностью, а простота использования и определенно не подходит для обработки больших объемов данных.
Ответ 7
Как использовать JSON для формата хранения/загрузки данных? Я понятия не имею, как быстро парсер JSON находится в PHP, но обычно он работает быстро на большинстве языков и имеет легкий формат.
http://php.net/manual/en/book.json.php
Ответ 8
SQLite поставляется с PHP, вы можете использовать его как свою базу данных. В противном случае вы можете попробовать использовать сеансы, тогда вам не нужно сериализовать что-либо, вы просто сохраняете необработанный объект PHP.