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, чтобы сделать его выполнимым.

Ответ 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.