Парсинг XML. SAX. Большая нагрузка на процессор.

CJ_Slade

Новичок
Парсинг XML. SAX. Большая нагрузка на процессор.

PHP:
$xml_parser = xml_parser_create("UTF-8");
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true);
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
		
$file = fopen($tmp_file,"r");
if ($file) 
	{
	while ($buf = fread($file,4096)) 
		{
		xml_parse($xml_parser, $buf,feof($file)));
            	}     
    fclose($file);
}
$tmp_file - XML файл в 32 мб (в дальнейшем будет в 300мб). Все обработчики "startElement", "endElement" и "characterData" содержат заглушки "return"
Проблема в том что при выполнении xml_parse нагрузка на процессор достигает 60%. Как можно сократить её?
 

A1x

Новичок
если критична загрузка процессора можно запускать задачу с более низким приоритетом (команда nice в *nix)

хтя имхо пхп - плохой выбор для обработки больших объемов данных. я как то сравнил пхп xml_parser с перл XML::parser на больших файлах - перл отрабатывает в 3 раза быстрее
 

CJ_Slade

Новичок
К сожалению полигон ограничен виртуальным хостингом. А на счет perl'а посмотрю, спасибо.
 

FB3

Новичок
Попробуйте воспользоваться SimpleXML. ИМХО, на данный момент - самый актуальный способ для парсинга XML в PHP.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Ваше имхо - однобоко. Это разные парсеры, и для разных целей. Написао же русским языком - файл до 300 мб.
 

slach

Новичок
FB3 - если данных много то не надо советовать SimpleXML
слишком много памяти жрет

попробуйте XMLReader интерфейс
http://ru2.php.net/manual/en/book.xmlreader.php

это в целом тоже SAX модель, но более гибкая
и может оно просто реализовано с точки зрения php ЛУЧШЕ и более щадящем режиме к CPU за счет того что более правильно интеграровано с libxml2
 

tony2001

TeaM PHPClub
но вообще, конечно, постановка вопроса интересная: "есть 32Mb XML, почему его парсинг нагружает процессор?"
да потому, что это XML. потому, что его 32Mb.
никогда и нигде это быстро и без нагрузки на проц не будет парситься.
 

CJ_Slade

Новичок
Быстро и не нужно, главное в ресурсное пространство вписаться.
 

FB3

Новичок
Автор оригинала: tony2001 никогда и нигде это быстро и без нагрузки на проц не будет парситься.
Не, ну в принципе можно свой модуль на C/C++ для PHP написать, вдруг получится сделать более качественно, чем у разработчиков PHP :)

А вообще, насколько мне известно, конечно, XML не предназначен для таких объемов данных.
Остается только жалеть тех, кто над ним так изгаляется...

XML - прежде всего формат обмена данными, а не средство их хранения.
Данные нужно хранить и обрабатывать в БД...

Конечно, ситуации бывают разные и со всеми приходится как-то обходиться, но это не значит, что не надо напрягать тех, кто изначально это придумал.
 

Bakti9rov

!*|=?
CJ_Slade
Как насчет записи или конвертации в более простые форматы (в CSV, если структура XML несложная).

FB3
XML - прежде всего формат обмена данными, а не средство их хранения.
Данные нужно хранить и обрабатывать в БД...
данные удобнее хранить в базе. А попробуй экспортнуть >100Мб МБ в простой SQL дамп :). Вот и получаются XML файлы в 200-300Мб- данные записанные в избыточном формате.
 

tony2001

TeaM PHPClub
>Не, ну в принципе можно свой модуль на C/C++ для PHP написать, вдруг получится сделать более качественно, чем у разработчиков PHP

ну да, куда уж разработчикам PHP и libxml2 до вас.
 

FB3

Новичок
Автор оригинала: Bakti9rov данные удобнее хранить в базе. А попробуй экспортнуть >100Мб МБ в простой SQL дамп :). Вот и получаются XML файлы в 200-300Мб- данные записанные в избыточном формате.
Смотря с какой целью экспортить. Чтобы заимпортить потом куда-то, например в другую БД, то есть для одноразовой обработки - то почему бы и нет.
А если потом выборку из них делать, то почему бы не сделать выборку в БД и потом уже заэкспортить полученный результат.
 

Макс

Старожил PHPClub
Автор оригинала: CJ_Slade
Быстро и не нужно, главное в ресурсное пространство вписаться.
тогда просто в цикле после xml_parse() поставь usleep() 1000 - 100000 (число экспериментально подбирается)
 
Сверху