Большой XML файл.
От: hellas Россия  
Дата: 26.10.06 04:13
Оценка:
Есть большой XML файл. Порядка полугига. Его надо преобразовать в другой формат.
Есть ли готовые решения, которые не пытаются загрузить файл в память?
Нужно что-то чтобы читало его последовательно.
This software required Windows 95 or better...
So I installed Linux
Re: Большой XML файл.
От: Tonal- Россия www.promsoft.ru
Дата: 26.10.06 04:58
Оценка:
Здравствуйте, hellas, Вы писали:

H>Есть большой XML файл. Порядка полугига. Его надо преобразовать в другой формат.

...
H>Нужно что-то чтобы читало его последовательно.
SAX парсер тебе в руки.
Точно идёт в составе msxml.
expat тоже SAX поддерживает.
Re: Большой XML файл.
От: c-smile Канада http://terrainformatica.com
Дата: 26.10.06 05:09
Оценка: 7 (1)
Здравствуйте, hellas, Вы писали:

H>Есть большой XML файл. Порядка полугига. Его надо преобразовать в другой формат.

H>Есть ли готовые решения, которые не пытаются загрузить файл в память?
H>Нужно что-то чтобы читало его последовательно.

Вот это http://www.codeproject.com/cpp/HTML_XML_Scanner.asp я делал как раз для таких целей.
Это т.н. push parser — теоретически это самый быстрый способ потоковой обработки XML.
Re[2]: Большой XML файл.
От: hellas Россия  
Дата: 26.10.06 05:55
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, hellas, Вы писали:


H>>Есть большой XML файл. Порядка полугига. Его надо преобразовать в другой формат.

H>>Есть ли готовые решения, которые не пытаются загрузить файл в память?
H>>Нужно что-то чтобы читало его последовательно.

CS>Вот это http://www.codeproject.com/cpp/HTML_XML_Scanner.asp я делал как раз для таких целей.

CS>Это т.н. push parser — теоретически это самый быстрый способ потоковой обработки XML.


А можно пример обработки файла?
This software required Windows 95 or better...
So I installed Linux
Re[3]: Большой XML файл.
От: c-smile Канада http://terrainformatica.com
Дата: 26.10.06 16:15
Оценка:
Здравствуйте, hellas, Вы писали:

CS>>Вот это http://www.codeproject.com/cpp/HTML_XML_Scanner.asp я делал как раз для таких целей.

CS>>Это т.н. push parser — теоретически это самый быстрый способ потоковой обработки XML.


H>А можно пример обработки файла?


Если я правильно понял вопрос...

Вот самый наипростейший файловый входной stream для сканера

struct file_istream: public markup::instream
{
  FILE *f;
  file_istream(const char* src): f(0) { f = fopen(...); }
  virtual wchar_t get_char() { int t = fgetc(f); return (t == EOF)? 0 : t; }
};


Если в XML используется encoding отличный от ascii то

virtual wchar_t get_char() { if(feof(f)) return 0; return fgetc(f); }

должна делать преобразование в wchar_t

Это самый наипростейший вариант входного потока. В зависимости от потребностей могут быть разные оптимизации.
Re[2]: Большой XML файл.
От: korzhik Россия  
Дата: 26.10.06 21:11
Оценка: 26 (1) +1
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, hellas, Вы писали:


H>>Есть большой XML файл. Порядка полугига. Его надо преобразовать в другой формат.

H>>Есть ли готовые решения, которые не пытаются загрузить файл в память?
H>>Нужно что-то чтобы читало его последовательно.

CS>Вот это http://www.codeproject.com/cpp/HTML_XML_Scanner.asp я делал как раз для таких целей.

CS>Это т.н. push parser — теоретически это самый быстрый способ потоковой обработки XML.

Помоему это называется pull parser, нет?
Re: Большой XML файл.
От: Аноним  
Дата: 29.10.06 21:22
Оценка:
Здравствуйте, hellas, Вы писали:

H>Есть большой XML файл. Порядка полугига. Его надо преобразовать в другой формат.

H>Есть ли готовые решения, которые не пытаются загрузить файл в память?

Лучше всего воспользоватся стандартными решениями. А стандартные решения это SAX парсеры и expat.
В MSXML 3 (вроде, может и раньше) и выше входит СОМ-базированный SAX парсер. xerces-c- чистый С++. Скорость великолепная у обоих — гарантирую, что парсер боттлнеком не станет. Думаю что на "пропарсить полгигабайта" уйдёт 30-60 сек (на типичном компьютере) — на обработку аутпута (пихать в БД?) времени наверняка уйдёт значительно больше.
expat — произведение исскусства, но может показатся чересчур низкоуровневым.

С самоделками лучше не связыватся — ХМЛ парсер оттестировать — всем миром надо повозится, всякие энкодинги, всевозможные конструкции — даже в упомянутых парсерах кой-какие проблемы встречаются и кое-что не иплементировано. Кроме того, SAX для валидации инпута может пользоватся схемой.
Re[2]: Большой XML файл.
От: Аноним  
Дата: 29.10.06 21:52
Оценка:
Кстати, при написании SAX-клиента — удобно пользоватся стеком (в смысле структуры данных) — Sax start element -> stack push, Sax end element -> stack pop.
У меня даже есть генерический фреймворк для написания такого кода (задача легко генерализутся и позволяет большую часть имплементировать раз и навсегда). Выложил бы в опен соурс, но неудобно — код не "отточен", документации нет, кроме автора никто не разберётся, нынешний вариант работает только с майкрософтским SAX-ом (легко исправить). А на приведение в порядок времени, естественно, нет.
Re[3]: Большой XML файл.
От: c-smile Канада http://terrainformatica.com
Дата: 29.10.06 22:48
Оценка:
Здравствуйте, korzhik, Вы писали:

K>Помоему это называется pull parser, нет?


Точно так. Спасибо.
Re[4]: Большой XML файл.
От: korzhik Россия  
Дата: 30.10.06 03:45
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, korzhik, Вы писали:


K>>Помоему это называется pull parser, нет?


CS>Точно так. Спасибо.


Да, кстати, pull парсинг крутая вещь.
К сожалению я не видел C++ версии для промышленного использования.
Re[5]: Большой XML файл.
От: korzhik Россия  
Дата: 30.10.06 03:56
Оценка:
Здравствуйте, korzhik, Вы писали:

K>К сожалению я не видел C++ версии для промышленного использования.


Соврал. Видел, один раз, вот: http://xmlsoft.org/xmlreader.html
Re[6]: Большой XML файл.
От: Аноним  
Дата: 30.10.06 07:10
Оценка: 9 (1)
Здравствуйте, korzhik, Вы писали:

K>>К сожалению я не видел C++ версии для промышленного использования.


Есть ещё штука которая называется xmlbooster — генерирует XML парсеры. Для шарпа — даже бесплатно, для других языков — за деньги. В какую сторону это потом работает — не знаю, может и pull.

Leif — упоминаю для порядка из-за его несуразной дороговизны и runtime fee за каждый deployment (про fee — отдельный договор, за сколько-то (1500?) долларов уплаченных за лицензию вы можете только девелопить 1 год) — в нём раньше был XML Reader вроде нетовского. Потом он вроде исчезал — парсилось как в DOM-e, сразу в память и никаких вариантов — может обратно появился. Парсеры генерируемые им — С++ классы, репрезентирующие XML элементы. Какие-то странности — вроде как отдельный элемент из представления распарсенного файла вы можете получить только по значению (если в нем 100 000 и 100 МБ данных — немного неэффективно). Страшенные имена — читать никак. Часть парсера — в closed source DLL.
Мне раз пришлось заменять Leif на xerces-c DOM — код стал меньше (!), проще, легче и быстрее(!).
Re[7]: Большой XML файл.
От: korzhik Россия  
Дата: 30.10.06 07:46
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, korzhik, Вы писали:


K>>>К сожалению я не видел C++ версии для промышленного использования.


А>Есть ещё штука которая называется xmlbooster — генерирует XML парсеры. Для шарпа — даже бесплатно, для других языков — за деньги. В какую сторону это потом работает — не знаю, может и pull.


Интересная штука, надо будет потестировать потом на наших задачах.
Re[2]: Большой XML файл.
От: remark Россия http://www.1024cores.net/
Дата: 31.10.06 16:23
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Вот это http://www.codeproject.com/cpp/HTML_XML_Scanner.asp я делал как раз для таких целей.

CS>Это т.н. push parser — теоретически это самый быстрый способ потоковой обработки XML.

А в чём причина того, что pull парсер быстрее push? В чём фишка?
В чём прикол организовывать цикл в пользовательском коде, в не в коде библиотеки?


1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[3]: Большой XML файл.
От: korzhik Россия  
Дата: 31.10.06 17:14
Оценка:
Здравствуйте, remark, Вы писали:

R>Здравствуйте, c-smile, Вы писали:


CS>>Вот это http://www.codeproject.com/cpp/HTML_XML_Scanner.asp я делал как раз для таких целей.

CS>>Это т.н. push parser — теоретически это самый быстрый способ потоковой обработки XML.

R>А в чём причина того, что pull парсер быстрее push? В чём фишка?

R>В чём прикол организовывать цикл в пользовательском коде, в не в коде библиотеки?

Более естественный на мой взгляд интерфейс для работы с XML.
В принципе если прогнать SAX парсер и pull парсер впустую на каком нибудь большом файле, то разница будет мизерная, если вообще будет.

Выигрыш даётся засчёт более удобного интерфейса.

В моём приложении я использую expat, но было дело, тестировал c-smile pull parser.
Тестировал на 30Мб XML файле.

С expat парсинг и построение dom 3 сек
С pull почти 2 сек

То есть выигрыш приближался к 30%

Но, ещё раз замечу, это не сравнение скорости парсеров, а сравнение различных подходов, то есть для тестирования pull парсера пришлось менять всю обработку данных.
И в итоге получить выигрыш за счёт болле удобного интерфейса
Re[4]: Большой XML файл.
От: remark Россия http://www.1024cores.net/
Дата: 31.10.06 18:41
Оценка:
Здравствуйте, korzhik, Вы писали:

K>Здравствуйте, remark, Вы писали:


R>>Здравствуйте, c-smile, Вы писали:


CS>>>Вот это http://www.codeproject.com/cpp/HTML_XML_Scanner.asp я делал как раз для таких целей.

CS>>>Это т.н. push parser — теоретически это самый быстрый способ потоковой обработки XML.

R>>А в чём причина того, что pull парсер быстрее push? В чём фишка?

R>>В чём прикол организовывать цикл в пользовательском коде, в не в коде библиотеки?

K>Более естественный на мой взгляд интерфейс для работы с XML.

K>В принципе если прогнать SAX парсер и pull парсер впустую на каком нибудь большом файле, то разница будет мизерная, если вообще будет.

K>Выигрыш даётся засчёт более удобного интерфейса.


K>В моём приложении я использую expat, но было дело, тестировал c-smile pull parser.

K>Тестировал на 30Мб XML файле.

K>С expat парсинг и построение dom 3 сек

K>С pull почти 2 сек

K>То есть выигрыш приближался к 30%


K>Но, ещё раз замечу, это не сравнение скорости парсеров, а сравнение различных подходов, то есть для тестирования pull парсера пришлось менять всю обработку данных.

K>И в итоге получить выигрыш за счёт болле удобного интерфейса

Но всё-таки суть в чём?
Удобный интерфейс не тянет на первопричину повышения производительности
Сходу приходит в голову следующее: pull-парсер за счёт ручного "управления" процессом позволяет делать меньше лишней работы. Т.е. например, не создавать объект с аттрибутами (копировать строку со значением аттрибута), если пользовательский код не будет анализировать и считывать аттрибуты. Т.о. часть лишней работы подавляется.
А в остальном, я пока не вижу какого принципиального отличия между моделями, которые могли бы как-то влиять на производительность.

Хотя вот сейчас я подумал, что Push-парсер тоже может не делать никакой лишней работы, пока пользователь не запросит. Например, если пользователь не обращается к какому-то аттрибуту, то его значение может не копироваться. Т.е. вся реальная работа только по запросу пользователя. Хотя наверное так не делают (точнее просто не сделано) в популярных парсерах.


1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[5]: Большой XML файл.
От: korzhik Россия  
Дата: 31.10.06 20:12
Оценка:
Здравствуйте, remark, Вы писали:

R>Удобный интерфейс не тянет на первопричину повышения производительности


а почему нет

R>Сходу приходит в голову следующее: pull-парсер за счёт ручного "управления" процессом позволяет делать меньше лишней работы. Т.е. например, не создавать объект с аттрибутами (копировать строку со значением аттрибута), если пользовательский код не будет анализировать и считывать аттрибуты. Т.о. часть лишней работы подавляется.

R>А в остальном, я пока не вижу какого принципиального отличия между моделями, которые могли бы как-то влиять на производительность.

и это тоже

R>Хотя вот сейчас я подумал, что Push-парсер тоже может не делать никакой лишней работы, пока пользователь не запросит. Например, если пользователь не обращается к какому-то аттрибуту, то его значение может не копироваться. Т.е. вся реальная работа только по запросу пользователя. Хотя наверное так не делают (точнее просто не сделано) в популярных парсерах.


вот это не знаю
Re[4]: Большой XML файл.
От: remark Россия http://www.1024cores.net/
Дата: 01.11.06 06:37
Оценка:
Здравствуйте, korzhik, Вы писали:

R>>А в чём причина того, что pull парсер быстрее push? В чём фишка?

R>>В чём прикол организовывать цикл в пользовательском коде, в не в коде библиотеки?

А вот тут тоже можно, пожалуйста, поподробнее.
Вот что я пока вижу.
1. Необходимость организовывать цикл вручную, вместо цикла один раз написанного и внесённого в библиотеку. Имхо это минус.
2. С полпинка можно попытаться, например, получить значение аттрибута у парсера, когда на самом деле парсим не аттрибут, а элемент. Имхо большой минус. В push модели отлов таких ошибок будет на стадии компиляции. Т.е. если мы попали в калбек elementStart(const String& elementName). Значит ни к каким аттрибутум доступ мы просто не получим.
Это относится по крайней мере к тому интерфейсы парсера, который я вижу сейчас.

Других отлчий пока не вижу.


1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[5]: Большой XML файл.
От: korzhik Россия  
Дата: 01.11.06 06:52
Оценка: 7 (1) +1
Здравствуйте, remark, Вы писали:

R>Здравствуйте, korzhik, Вы писали:


R>>>А в чём причина того, что pull парсер быстрее push? В чём фишка?

R>>>В чём прикол организовывать цикл в пользовательском коде, в не в коде библиотеки?

R>А вот тут тоже можно, пожалуйста, поподробнее.

R>Вот что я пока вижу.
R>1. Необходимость организовывать цикл вручную, вместо цикла один раз написанного и внесённого в библиотеку. Имхо это минус.
R>2. С полпинка можно попытаться, например, получить значение аттрибута у парсера, когда на самом деле парсим не аттрибут, а элемент. Имхо большой минус. В push модели отлов таких ошибок будет на стадии компиляции. Т.е. если мы попали в калбек elementStart(const String& elementName). Значит ни к каким аттрибутум доступ мы просто не получим.
R>Это относится по крайней мере к тому интерфейсы парсера, который я вижу сейчас.

такие ошибки возможны, согласен.

pull парсер средство более низкоуровневое чем SAX. И наверняка SAX парсеры строятся на основе pull парсера. Более низкоуровневое средство требует более высокой дисциплины

Я, к сожалению не могу сейчас аргументированно доказать что вот прям pull парсинг крутая вещь.
Но на своей задаче я пробовал pull парсинг, это сделало код обработки проще и быстрее, вот всё что я могку сказать.

Наверно чтобы полностью разобраться, надо поставить какую то небольшую задачу и решить её с помощью двух подходов: SAX и pull
Re[4]: Большой XML файл.
От: Аноним  
Дата: 01.11.06 08:52
Оценка:
Здравствуйте, korzhik, Вы писали:

K>С expat парсинг и построение dom 3 сек

K>С pull почти 2 сек

K>То есть выигрыш приближался к 30%


Мне такое сравнение кажется несовсем корректным: expat способен обрабатывать, мягко говоря, несколько больше ситуаций, чем упомянутый парсер. Доведите функционал этого парсера до того, что есть в expat-е (а меньше — это ещё не настоящий парсер) — и еще не известно, кто будет быстрее. Полноценный ХМЛ парсинг — больше чем разбор строки на элементы и аттрибуты, выудить же элемент или что-то в этом роде из файла (с известым заранее энкодингом) — можно и используя регулярные выражения, например — может и ещё быстрее получится. По моему вы разные вещи сравниваете.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.