LINUX.ORG.RU

Парсинг XML файлов


0

1

Всем доброго времени суток. Пишу программу для парсинга XML файлов. Столкнулся с проблемой, что при считывания XML файла размером в сотни Мб, программа надолго задумывается. Считываю с файла по байту в массив, далее этот массив перекодировываю. И запускаю обработчик этого файла. Передаю массив по ссылке в функции, но программа все равно работает медленно. На разбор 2000 строк уходит примерно минута. Можете посоветовать, как оптимизировать программу?

Можешь глянуть как в pugi::xml устроенно, он достаточно быстр.

sol_linux ★★
()

Есть же парсеры, как их… SAX?

Deleted
()

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

TheKnight ★★★
()

Думаю нужен твой код

vertexua ★★★★★
()
Ответ на: комментарий от TheKnight

Можешь глянуть как в pugi::xml устроенно, он достаточно быстр.

libxml2

Есть же парсеры, как их… SAX?

SAX? DOM?

Читал про эти либы, но я не хочу их использовать. Хотелось бы ручками.

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

Пишу на C++. Считываю весь файл сразу, программа тупит когда обратбатываю, строю дерево.

JuST_KoReaN
() автор топика
Ответ на: комментарий от JuST_KoReaN

Читал про эти либы, но я не хочу их использовать. Хотелось бы ручками.

Парсить XML руками? Мало того, что «ручками» ты распарсишь не XML, а фигню с угловыми скобочками, это будет еще и медленнее. И да, для сотен мегабайт XML придумали SAX.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Парсить XML руками? Мало того, что «ручками» ты распарсишь не XML, а фигню с угловыми скобочками, это будет еще и медленнее. И да, для сотен мегабайт XML придумали SAX.

Добиваюсь не того, чтобы работало быстрее чем SAX, DOM и т. д. Хочу сделать свой парсер, своими руками, не для проекта. Пытаюсь разобраться.

JuST_KoReaN
() автор топика
Ответ на: комментарий от JuST_KoReaN

http://ru.wikipedia.org/wiki/SAX Почитай и пойми принцип. XML самописный? Является ли пример XML'ки секретным? Ну не верю я, что так все может тормозить...

Ну и да - выложи куски исходного кода, где собственно вся бодяга и происходит. Возможно тебе стоит поиграться с обработкой строк правильной. Может и не в этом дело.

В общем «довольно слов, покажите мне код!»

TheKnight ★★★
()
Ответ на: комментарий от JuST_KoReaN

Добиваюсь не того, чтобы работало быстрее чем SAX, DOM и т. д.

Для начала разберись, что такое SAX и DOM. Подсказка - это не парсеры, а API.

Хочу сделать свой парсер, своими руками, не для проекта.

Надеюсь, ты уже изучил стандарт XML.

tailgunner ★★★★★
()

читываю с файла по байту в массив

Ну этим всё сказано. Возможно всё остальное на том же уровне. Используй буфер и читай сразу в него

Считываю весь файл сразу, программа тупит когда обратбатываю, строю дерево.

Как узнал? Таким же способом узнай тогда, где именно

Zorn
()

Считываю с файла по байту в массив

Вот даже тут уже тормоза. Читай блоками или сразу одним блоком размером в файл. Или делай mmap-инг этого файла в память, в любом случае получишь ощутимый прирост производительности. Наилучший вариант, наверное, читать файл блоками и тут же эти блоки обрабатывать, не забивая в ОЗУ целый файл.

Далее, ты руками разбираешь строку из xml-токенов. Тут может быть огромное множество тормозов, начиная с плохого алгоритма и заканчивая мелкими нюансами вроде неоптимальной работы с памятью, которую ты можешь не замечать за использованием std::контейнеров.

Продолжаем. Возможно, для твоей задачи совсем не обязательно парсить весь файл и строить DOM (дерево), может достаточно SAX (простейший последовательный проход по токенам)?

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

staseg ★★★★★
()
Ответ на: комментарий от tailgunner

Лорчую, ОП прочитай про них, хотя бы в wiki.

anonymous
()

Обычно оптимизация начинается с профилирования.

Apple-ch ★★
()
Ответ на: комментарий от Zorn

у меня тормозит в нескольких местах:

  • стадия проверки кодировки. Чтобы различить ANSI от UTF-8 (BOM && without BOM) читаю биты у одного байта. Так как латиница у них одинакова, он долго доходит до символа кириллицы, а там уже определяет кодировку.
  • и разбор самого перекодированного буфера, операции добавления тэга, атрибутов, текста между тэгов, комментария проходят быстро по отдельности. Но при разборе всего буфера текста - тормозит

Проверял Debug'ом

JuST_KoReaN
() автор топика

Читай исходники libxml2, ищи узкие места в своем коде.

XML файла размером в сотни Мб .... На разбор 2000 строк ....

Это явно не сотни мегабайт.

Ну и да, xml размером в сотни мегабайт _не_нужны_.

unfo ★★★★★
()
Ответ на: комментарий от JuST_KoReaN

переходи на Qt.
прочитай про парсеры и лексеры.
может тормозит построение дерева? замерь время разбора:

165. check_xml();

и время построения:

167. tree.print(TreeView);

там у TTreeView должны быть функции BeginUpdate и EndUpdate.
попробуй выкинуть само дерево «TagContainer tree». выводи для начала в файл, увидишь какая часть работает медленнее, ту и оптимизировать будешь. значения аргументов тегов могут быть не в кавычках, могут содержать внутри себя кавычки, могут содержать внутри себя пробелы.

anonymous
()
Ответ на: комментарий от JuST_KoReaN

Весь код читать лень, но вот это:

for (i = 0; i < strlen(*c); i++)

гарантированные тормоза.

Делай или так:

for (i = strlen(*c); i > 0; i--)

или так:

len = strlen(*c);
for (i = 0; i < len; i++)

или совсем по сишному:

char *c_i;
for (c_i = *c; *c_i != 0; c_i++)

cdslow ★★
()
Ответ на: комментарий от cdslow

Ок, исправил, действительно работает быстрее. Намного

JuST_KoReaN
() автор топика
Ответ на: комментарий от cdslow

А вот еще вопрос, я при каждом добавлении тега выделяю буфер в куче (динамически), может быть создать глобальный буфер с фиксированной величиной? Может ли от этого тормозить программа?

JuST_KoReaN
() автор топика

при считывания XML файла размером в сотни Мб

mmap используется?

quest ★★★★
()

Можете посоветовать, как оптимизировать программу?

ничего не считывать в память, использовать mmap. если потом к XML идет много запросов - строить индексы

quest ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.