2011-12-14 3 views
0

У меня есть php-файл, который должен читать сотни XML-файлов, у меня нет выбора, как эти XML-файлы создаются, они создаются третьей стороной.Ускорение чтения нескольких файлов XML в PHP

Первый xml-файл представляет собой большое количество заголовков для остальных xml-файлов, поэтому я ищу первый XML-файл, чтобы получить имена файлов для остальных xml-файлов.

Затем я читал каждый XML-файл, ища его значения для определенной фразы.

Этот процесс очень медленный. Я говорю 5 1/2 минуты времени автономной работы ... Что неприемлемо для веб-сайта, клиенты не останутся надолго.

Кто-нибудь знает способ, который мог бы ускорить мой код, до максимальной продолжительности работы около 30 секунд.

Вот Pastebin моего кода: http://pastebin.com/HXSSj0Jt

Спасибо, извините за непонятный английский ...

+0

У меня есть cachegrind.out, а часть, которая занимает время, - это SimpleXMLElement -> __ Construct this в среднем принимает 1.98s – Aaron

+0

Это будет в основном время загрузки. Попробуйте разделить процесс загрузки и xml, используйте file_get_contents() или curl для поддержки gzip. – goat

+0

Прошу отличить. Это не всегда просто время загрузки. Если XML большой, требуется много памяти и времени для создания DOM из XML в случае использования DOM/SimpleXML. Поэтому, если нет возможности избежать обработки больших XML-файлов, единственным методом выбора являются потоковые (XMLReader)/основанные на события (SAX) синтаксические анализаторы. DOM в таких сценариях просто не работает. – cryo28

ответ

1

Вашей основной проблемой является вы пытаетесь сделать сотни загрузки HTTP для выполнения поиска. Если вы не избавитесь от этого ограничения, это будет только так быстро.

Если по какой-то причине файлы не являются доступными для (маловероятно), даже в некоторых случаях вы можете получить некоторую скорость, загрузив их параллельно. См. Функции curl_multi _ *(). Альтернативно, используйте wget из командной строки с xargs для загрузки в параллель.

Вышеупомянутое звучит безумно, если у вас есть какой-то трафик.

Скорее всего, файлы могут быть кэшированы как минимум на короткое время. Посмотрите на заголовки http и посмотрите, какую информацию о свежести посылает их сервер. Он может сказать, как долго истекает срок действия файла, и в этом случае вы можете сохранить его локально до тех пор. Или это может дать последний измененный или etag, и в этом случае вы можете выполнить условные запросы на получение, что должно ускорить работу.

Я бы, вероятно, установил местный squid cache и попросил php выполнить эти запросы через кальмара. Он позаботится о том, чтобы использовать локальную копию, если она свежее или условно извлекает для вас логику новой версии.

Если вы все еще хотите повысить производительность, вы можете преобразовать файлы в кеш-файлы в более подходящий формат (например, вставьте соответствующие данные в базу данных). Или, если вы должны придерживаться формата xml, сначала вы можете выполнить строковый поиск в файле, чтобы проверить, следует ли вообще анализировать этот файл как xml.

+0

Я просмотрел заголовки, я думаю, что хорошо обновлять кеш раз в месяц. Как я могу построить такой кеш? Мне нужно будет локально загрузить все 500 или около того xml-файлов, а затем убедитесь, что они обновляются каждый месяц ... – Aaron

+1

Я бы просто создал таблицу базы данных с полями «tripcode», «country» и «xml». запустите php-скрипт через задание cron раз в месяц, чтобы обновить базу данных. Теперь вы можете быстро найти базу данных. – goat

1

Прежде всего, если вам приходится иметь дело с большим XML-файлами для каждого запроса к вашей услуге, разумно загружать один раз, препроцессор xml и кэшировать их локально.

Если вы не можете предварительно обрабатывать и кэшировать xml и загружать их для каждого запроса (что, на мой взгляд, я действительно не верю, это так), вы можете попробовать оптимизировать с помощью XMLReader или некоторого синтаксического анализа XML на основе событий SAX. Проблема с SimpleXML заключается в том, что он использует DOM внизу. DOM (как обозначают буквы) создает объектную модель документа в вашей памяти процесса php, которая занимает много времени и поглощает массу памяти. Я бы рискнул сказать, что DOM бесполезен для синтаксического анализа больших XML-файлов.

Принимая во внимание, что XMLReader позволит вам перемещаться по узлу большого узла по узлу, не имея при этом ничего общего с компромиссом, с которым вы не можете отправлять запросы xpath или любые другие шаблоны доступа, не связанные друг с другом.

Как использовать XmlReader вы можете проконсультироваться с php manual for XMLReader extension

Смежные вопросы