Форум: "Прочее";
Текущий архив: 2013.06.16;
Скачать: [xml.tar.bz2];
ВнизXML: Проект "ApolloSAX" Найти похожие ветки
← →
DevilDevil © (2013-02-01 11:18) [0]Доброе время суток всем
Пишу здесь, потому что посетила мою голову навязчивая идея. Я подумал, что если изложу свои мысли здесь, то вполне возможно, что из идеи в итоге выйдет достойный проект
Пара слов об XML
Я думаю ни для кого не секрет, что XML плотно засел в современные информационные технологии. Его используют везде. Раньше я видел только одно предназначение XML - файлы настроек. Однако сегодня его используют в Веб, тех же самых мессенджерах, форматы файлов стали активно строить на XML. Немалый вклад в укоренение XML на мой взгляд стала технология Office Open XML, разработанная компанией Microsoft. Да что тут говорить, даже старый добрый HTML всё чаще и чаще заменяют XHTML. Совсем недавно обнаружил, что мой любимый "MindManager" тоже использует OOXML для своих файлов.
Пара слов обо мне
Программирую 14 лет. Люблю Delphi, неплохо знаю ассемблер x86, С/C++ тоже немного знаю (2.5 года официальной работы). Моя стихия - это оптимизации и удобный пользовательский интерфейс (тоже в некотором роде оптимизация - эффективности деятельности пользователя). Имею опыт генерации и распарсивания XML/HTML с очень хорошей скоростью. Тестировали с разными парсерами - получилось что-то между pugiXML и Expat, ближе к pugi. С другой стороны парсер понимал только Ansi и Utf8, не мог обрабатывать CDATA. В общем достаточно неуниверсальный парсер
Зачем ещё один парсер
Я думаю многие со мной согласятся. Несмотря на обилие достойных SAX и DOM парсеров, вопрос идентификации элементов/атрибутов, производительности, валидации, удобства использования - по прежнему остаётся актуальным. Проект который я предлагаю сделать - максимально упрощает жизнь вышеописанную рутинную работу
В чём состоит идея
Идея проста и гениальна. В большинстве случаев, распарсивая сложный (или простой) XML, мы уже разумеется знаем его строение. По умному - если предполагается обмениваться XML, то к нему существует XSD-схема (или схема в другом формате). Для идентификации имён элементов и атрибутов мы используем различные алгоритмы, чтобы в конечном счёте строку-идентификатор преобразовать к целочисленной константе. Достаточно эффективен поиск таких идентификаторов в хеш-таблице. Но это накладные расходы: хеш-функция, поиск в массиве, коллизии, перераспределение массива, надо делать сверки строк. Лично я для подобных случаев разработал более эффективный способ. Я написал утилиту, которая имеет на входе ряд идентификаторов, а на выходе выдаёт оптимальную функцию на ЯВУ, позволяющую однозначно определять идентификаторы. К примеру если я знаю, что элемент имеет одно из имён: "sheet","row","cell","data","value","style" - то код позволяющий мне определить элемент, будет выглядеть так. TAnsiPointer - это мой внутренний тип, хранящий длину строки и указатель на её символы. Мне очень нравится :)const
ID_UNKNOWN = 0;
ID_CELL = 1;
ID_DATA = 2;
ID_ROW = 3;
ID_SHEET = 4;
ID_STYLE = 5;
ID_VALUE = 6;
// generated by "Static Serializer"
function StrToSomeType(const S: TAnsiPointer): integer;
type
__TAnsiPointerData = packed record
case integer of
0: (chars: array[0..high(integer)-1] of ansichar);
1: (words: array[0..high(integer)div 2-1] of word);
2: (dwords: array[0..high(integer)div 4-1] of dword);
end;
begin
Result := ID_UNKNOWN;
{ case sensitive, ansi }
with __TAnsiPointerData(pointer(S.Data)^) do
case (S.Length) of
3: if (words[0]=$6F72)and(chars[2]="w") then Result := ID_ROW;
4: case (dwords[0]) of
$6C6C6563: Result := ID_CELL;
$61746164: Result := ID_DATA;
end;
5: case (dwords[0]) of
$65656873: if (chars[4]="t") then Result := ID_SHEET;
$6C797473: if (chars[4]="e") then Result := ID_STYLE;
$756C6176: if (chars[4]="e") then Result := ID_VALUE;
end;
end;
end;
Но суть не в том. Суть в том, что
1) идентифицировать элементы и атрибуты можно на лету
2) генерировать целочисленные константы можно на лету
3) вся эта информация уже хранится в XSD
4) существует возможность проводить валидацию документа и преобразовывать данные к нужному формату тоже на лету. Например если ожидается число - то преобразовывать к числу, если дата - то к дате. Если нужно оставить строкой - ради бога.
5) в конкретный момент парсинга ожидается ограниченно малое количество идентификаторов: элементов/атрибутов. Это позволяет существенно сократить время идентификации очередного элемента/атрибута
6) ну и наконец, как человек таки написавший парсер, заявлю. С точки зрения производительности намного эффективнее парсить очередной элемент, когда ты знаешь, как он может называться. Это значительно эффективнее поиска скобочек, кавычек, спец знаков и тд. ... с дальнейшей их универсальной идентификацией
В целом я предлагаю разработать утилиту, которая позволяет открывать XSD-схему (или другие), выставлять им специфичные опции (например какие элементы/атрибуты пропускать или к каким типам приводить), а на выходе получать специально заточенные модули-парсеры *.pas (для Delphi/FreePascal) или *.h/*.c (для C/C++). В модулях будут объявлены все необходимые константы, а так же главная функция-парсер. Для Delphi она будет реализована в виде дампов машинного кода для платформ x86, x64, ARM. Для С/C++ будет реализация на ЯВУ, но тоже мега запутанная. Главное в этих функциях не читабильность, а стабильная эффективная работа и компилируемость.
Парсер по сути состоит из двух частей: модуль-парсер, заточенный по конкретному XSD, и один универсальный модуль, в котором будут располагаться вспомогательные функции и так же рутина для потокового чтения. Под потоковым чтением я подразумеваю эффективное чтение данных например из файла (или того же zip) и автоматическое переконвертирование в случае необходимости в нужную кодировку
На кого ориентировано
1) кому нужно обрабатывать огромные XML файлы с максимально возможной скоростью
2) кому очень хочется комфортного распарсивания с автоматической валидацией
3) кто хочет сделать DOM-чтение по конкретному XSD
Кто нужен в проект
один-два фаната XML, которые знают все его правила, знают подходы для парсинга, знают несколько эффективных реализаций
один знаток XSD который способен адекватно и в полной мере консультировать по всем особенностям схем
один-два классных специалиста, способных написать просмотрщик XSD (с возможностью выставлять наши специфические опции), с приятным и удобным пользовательским интерфейсом
один-два скептика, которые захотят на конкретных примерах доказывать, что наш парсер работает медленно и некорректно
я буду заниматься генерацией pas/h-c и вспомогательным модулем
Разумеется всё на энтузиазме
Хотя если у кого то возникнет желание разработать проект на материальной основе - буду рад продать свою идею и свой труд на его реализацию
← →
DevilDevil © (2013-02-01 11:18) [1]P.S.
Аполлон (Apollo) - бог света, наук, искусств и предсказаний в греческой мифологии, сын Зевса. Покровитель путешественников. На Олимпийских играх победил в беге Гермеса, а Ареса одолел в кулачном бою. "Никто из бессмертных не может сравниться по красоте с Аполлоном! Вечно молод он - высокий, стройный, золотоволосый бог". Наиболее известен в городе Дельфы (Delphi). Где одолел Пифона, основал Пифийские игры, и жил - весной и летом.
← →
Sergey Masloff (2013-02-01 11:48) [2]дальше в XSD схеме встречается xs:anyType и?
← →
DevilDevil © (2013-02-01 11:51) [3]> Sergey Masloff (01.02.13 11:48) [2]
в этом случае специфичный калбек. По аналогии со стандартными SAX-парсерами
← →
DevilDevil © (2013-02-02 00:07) [4]думаю проект таки будет называться ApolloXML
Почему речь вообще пошла о SAX
Дело в том, что существуют 2 основные схемы распознавания XML: SAX и DOM
Так вот, существуют различные задачи по обработке больших XML (100Мб и выше) с высокой скорость. И здесь SAX нет равных. По крайней мере не было.
И здесь родилась моя гениальная идея (да, я скромный). Что имея XSD мы можем существенно оптимизировать парсинг (сгенерировать конечный автомат), который будет автоматически определять идентификаторы элементов и атрибутов, и вызывать element_start() и attribute() уже не со строками в качестве имени, а уже с определёнными ID-константами, который определил парсер. Кроме того такой парсер (конечный автомат) очень легко может отслеживать неправильно или не в том порядке указанные элементы и атрибуты (валидация).
Потом я подумал, что значения атрибутов лучше тоже не всегда передавать строкой, а в случае определённого типа (числа, строковой константы, булеана, даты) - просто автоматически приводить данные к нужному типу и уже полученное значение передавать в калбек. Одновременно с этим вполне можно проводить валидацию значений! И это тоже будет проходить легко и непренуждённо!
Уже несколько суток я думаю следующее. Нафига вообще вызывать калбеки по атрибутам ?
Когда человек распарсивает элемент с атрибутами, элемент для него представляется некоей структурой. И XSD-утилита может генерировать описание такой структуры, и парсер будет в стеке выделять память под неё, заполнять все поля (в том числе по умолчанию), и в калбек уже передавать ID-структуры с указателем на данные структуры. Это мегаудобно. Кроме того это быстрее, чем дёргать калбек для каждого атрибута и заставлять пользователя его обрабатывать.
Ну и последние сутки я думаю, что на основе этого "SAX"-парсера, можно вполне сделать и DOM-парсер. Иначе говоря один парсер-"конечный автомат" одинаково хорошо может подходить и для SAX и для DOM. Фактически отличие только одно. Для SAX память под элементы будет выделяться в стеке, но для них будут вызываться калбеки. Для DOM память будет выделяться в пуле (такой способ менеджмента памяти) и наводить связи между Child-Parent ами. Серьёзными выигрышными сторонами такого DOM-решения по сравнению с тем же PugiXML и XML-Binding я считаю:
1) Максимально возможная производительность (из-за специально заточенной архитектуры парсера)
2) Практически бесплатная валидация (вообще это считается очень тяжёлой операцией). Но просто представьте, что вообще не надо будет заботиться о правильности введённых данных
3) Минимальное потребление памяти. Потому что не будет необходимости хранить в ОЗУ многочисленные строки
4) Супер удобство
P.S.
надо заботиться о пользователе
3 секунды значительно лучше, чем 10
← →
DevilDevil © (2013-02-02 00:09) [5]Кстати я накидал объявления типов. Хотя для *.h/*.c по идее будут аналоги
type
// внутренний тип строк, хранящий указатель на символьные данные, длинну и
// кодировку + высокоуровневые методы для извлечения строк стандартного типа
TApolloString = object
// todo
end;
// общая информация об элементе (узле)
PApolloNodeSAX = ^TApolloNodeSAX;
TApolloNodeSAX = object
private
FID: integer;
FLevel: integer;
FParent: PApolloNodeSAX;
FIndex: integer;
FUserData: pointer;
public
// однозначная идентификация элемента
// для каждого элемента в XSD есть соответствующая ID-константа
property ID: integer read FID;
// уровень вложенности элемента
// главный элемент имеет уровень 0, дочерние - 1
property Level: integer read FLevel;
// информация об элементе-отце
// у главного элемента Parent = nil
property Parent: PApolloNodeSAX read FParent;
// Parent.Childs[Index] = This
property Index: integer read FIndex;
// любая рабочая информация, указанная пользоватем
// главное не сохранять сюда рабочую структуру (Values)
// потому что область действия Values ограничивается только OnNodeStart
property UserData: pointer read FUserData write FUserData;
end;
// вызываемые при парсинге калбеки
TApolloEvent = procedure() of object;
TApolloNodeStart = function(const Node: TApolloNodeSAX; const Values: pointer): integer of object;
TApolloNodeFinish = procedure(const Node: TApolloNodeSAX) of object;
// структура, содержащая все необходимые калбеки
TApolloCallbacks = record
OnXmlBegin: TApolloEvent;
OnNodeStart: TApolloNodeStart;
OnNodeFinish: TApolloNodeFinish;
OnXmlEnd: TApolloEvent;
end;
// продвинутый вариант элемента, используется в DOM-парсинге
// отличается от SAX-варианта тем, что содержит все прочитанные данные (Values)
// а так же хранит информацию о потомках и удобные методы для работы
PApolloNodeDOM = ^TApolloNodeDOM;
TApolloNodeDOM = object
private
F: record
case Integer of
0: (ID: integer; Level: integer; Parent: PApolloNodeDOM; Index: integer; UserData: pointer);
1: (NodeSAX: TApolloNodeSAX);
end;
FValues: pointer;
FChild: PApolloNodeDOM;
FSibling: PApolloNodeDOM;
procedure SetIndex(const Value: integer);
procedure SetParent(const Value: PApolloNodeDOM);
public
property ID: integer read F.ID;
property Level: integer read F.Level;
property Parent: PApolloNodeDOM read F.Parent write SetParent;
property Index: integer read F.Index write SetIndex;
property UserData: pointer read F.UserData write F.UserData;
property AsNodeSAX: TApolloNodeSAX read F.NodeSAX;
// структура, в которой хранятся данные по элементу
property Values: pointer read FValues;
property Child: PApolloNodeDOM read FChild;
property Sibling: PApolloNodeDOM read FSibling;
{
procedure Delete;
property NextNode: PApolloNodeDOM read FSibling;
property PrevNode: PApolloNodeDOM read GetPrevNode;
property BottomChild: PApolloNodeDOM read GetBottomChild;
property NodesCount: integer read GetNodesCount;
property Nodes[const AIndex: integer]: PApolloNodeDOM read GetNode;
function NodeExists(const AID: integer): boolean;
function FindNode(const AID: integer; const recursion: boolean=false): PApolloNodeDOM;
}
end;
← →
имя (2013-02-02 10:52) [6]Удалено модератором
← →
KilkennyCat © (2013-02-02 13:17) [7]идея стоящая. могу потом тестером побыть, создать конфликтные ситуации.
← →
brother © (2013-02-02 13:25) [8]идея понравилась
← →
vuk © (2013-02-02 13:28) [9]А с кодировками правильно работать уже научились?
← →
wl © (2013-02-02 13:40) [10]
> vuk © (02.02.13 13:28) [9]
судя по первому посту этим должен заниматься отдельный модуль, что, в принципе правильно. отделение мух от котлет
← →
DevilDevil © (2013-02-02 14:09) [11]> KilkennyCat © (02.02.13 13:17) [7]
принято ;)
> brother © (02.02.13 13:25) [8]
спасибо
> vuk © (02.02.13 13:28) [9]
на 90% :)
← →
Pavia © (2013-02-02 14:30) [12]Поздравляю вы придумали идею 60-х годов на основе идеи 50-х годов.
Теперь по поводу ошибок.
> 6) ну и наконец, как человек таки написавший парсер, заявлю.
> С точки зрения производительности намного эффективнее парсить
> очередной элемент, когда ты знаешь, как он может называться.
> Это значительно эффективнее поиска скобочек, кавычек, спец
> знаков и тд. ... с дальнейшей их универсальной идентификацией
Это хорошо если у нас язык является простым, к примеру LR(1). Но в целом к XML это не относится.
> В целом я предлагаю разработать утилиту, которая позволяет
> открывать XSD-схему (или другие), выставлять им специфичные
> опции (например какие элементы/атрибуты пропускать или к
> каким типам приводить), а на выходе получать специально
> заточенные модули-парсеры *.pas (для Delphi/FreePascal)
> или *.h/*.c (для C/C++). В модулях будут объявлены все необходимые
> константы, а так же главная функция-парсер. Для Delphi она
> будет реализована в виде дампов машинного кода для платформ
> x86, x64, ARM. Для С/C++ будет реализация на ЯВУ, но тоже
> мега запутанная. Главное в этих функциях не читабильность,
> а стабильная эффективная работа и компилируемость.
А вот с этим не согласен. Генераторы компиляторов(генератор парсера) идя конечно интересная. Но практически ихмо от неё больше вреда чем пользы.
Основным должен стать внутренний формат программы, а не внутренний формат файла.
← →
vuk © (2013-02-02 14:44) [13]to DevilDevil © (02.02.13 14:09) [11]:
> на 90% :)
Я просто посмотрел на объем исходников, например, OpenXML/ADOM ( http://www.philo.de/xml/downloads.shtml )... Так там работа со всякими кодировками и преобразованиями - это где-то треть всего объема исходников.
← →
DevilDevil © (2013-02-02 14:48) [14]> Pavia © (02.02.13 14:30) [12]
> Поздравляю вы придумали идею 60-х годов на основе идеи 50-
> х годов. Теперь по поводу ошибок.
я отношусь к тем людям, которые мало ценят теории до тех пор, пока они не нашли достойного практического применения. Насколько я знаю, не существует парсеров, работающих по описанному мной принципу
> Это хорошо если у нас язык является простым, к примеру LR(1).
> Но в целом к XML это не относится.
я даже не знаю что здесь комментировать
даже так. я не понимаю, что заставило тебя прокомментировать моё изречение
> А вот с этим не согласен. Генераторы компиляторов(генератор
> парсера) идя конечно интересная. Но практически ихмо от
> неё больше вреда чем пользы.Основным должен стать внутренний
> формат программы, а не внутренний формат файла.
реализуй
лично я считаю, что предложенная тобой идея крайне сложно формализуемая для реализации. У меня перед глазами всплывает Excel-документ в формате XML. В каком ты там виде предполагаешь хранить информацию - понять сложно. А вот получить прочитанную в XML информацию и грамотно ей распоряжаться - это уже реальная задача, и эффективная
← →
xayam © (2013-02-02 14:49) [15]
> на 90% :)
каждый десятый символ в кракозябры ?
нет так не пойдёт :)
← →
Eraser © (2013-02-02 15:22) [16]
> DevilDevil © (01.02.13 11:18)
> В целом я предлагаю разработать утилиту, которая позволяет
> открывать XSD-схему (или другие), выставлять им специфичные
> опции (например какие элементы/атрибуты пропускать или к
> каким типам приводить), а на выходе получать специально
> заточенные модули-парсеры *.pas (для Delphi/FreePascal)
> или *.h/*.c (для C/C++). В модулях будут объявлены все необходимые
> константы, а так же главная функция-парсер. Для Delphi она
> будет реализована в виде дампов машинного кода для платформ
> x86, x64, ARM. Для С/C++ будет реализация на ЯВУ, но тоже
> мега запутанная. Главное в этих функциях не читабильность,
> а стабильная эффективная работа и компилируемость.
это никуда не годится и будет интересно только автору парсера.
вообще я бы посмотрел в сторону возможностей RTTI современных версий делфи, есть подозрение, что там многое можно в Runtime делать.
← →
DevilDevil © (2013-02-02 15:31) [17]> vuk © (02.02.13 14:44) [13]
глобально для парсинга я вижу 2 кодировки: Ansi и Utf8
алгоритмы переконвертирования utf-16 в utf-8, или же utf-16be|utf-32|utf-32be в utf-8 - открыты и достаточно доступны
c Ansi другая песня
имеется куча различных Ansi-кодировок, но!
у меня опять таки сгенерирован код, как по имени кодировки определить её кодовую страницу: http://ideone.com/T0nqep
а уже имея номер кодовой страницы можно получить таблицы UTF-16 символов для диапазона 128..255. По крайней мере в Windows мне это удавалось, в других ОС наверняка подходящий API существуют
← →
DevilDevil © (2013-02-02 15:36) [18]> Eraser © (02.02.13 15:22) [16]
> это никуда не годится и будет интересно только автору парсера.
прям вообще никуда не годится :)
ручная обработка строк в SAX/DOM/XML-Binding - значительно лучше :))
← →
Eraser © (2013-02-02 15:54) [19]
> DevilDevil © (02.02.13 15:36) [18]
мне, как и 99% пользователей все равно, как там внутри устроен парсер, но генерировать каждый раз новый pas файл при изменении структуры, это за пределами добра и зла. а если там сотня этих различных документов, что кстати, вполне себе реально в проектах, на которые заточен именно данный парсер.
← →
Pavia © (2013-02-02 16:08) [20]
> это никуда не годится и будет интересно только автору парсера.
Ты не поверишь, но на генератор-парсеков клюнет многу народу. Идея то что за тебя всё сделает умная машина очень заманчивая.
Так что проект будет очень популярным!
А вот когда вникаешь в суть. То выясняется:
1) приходиться очень хорошо изучать сам генератор.
2) приходиться всё описывать самому.
3) и генератор не способен работать с внутренней структурами. Так что приходиться писать конвертер, обёртку или семантический парсер.
← →
DevilDevil © (2013-02-02 16:23) [21]> Eraser © (02.02.13 15:54) [19]
я в последнее время говорю так
чтобы иметь право критиковать, даже самое малое - нужно иметь в арсенале достойную альтернативу
если тебе нужно парсить 100 разных документов, то ты будешь сам создавать 100 разных модулей, заточенных на распарсивание каждого. Только вместо готовых структур, констант и мегабыстрого парсера - ты возьмёшь стандартный парсер, и будешь для каждого узла и атрибута прописывать свою обработку со своим приведением типов. В итоге убьёшь недели труда, наделаешь ошибок и в результате получишь мизерную скорость. Это не альтернатива
> Pavia © (02.02.13 16:08) [20]
генератор изучать не придётся. Юзать только структуры и константы.
описывать всё самому тоже не придётся, это сделает утилита XSD --> pas
есть ли на данный момент "парсер", который сразу работает с твоими внутренними данными ? таки нет. Даже XML-Binding генерирует свою структуру. Которая крайне не оптимальна по производительности
← →
Eraser © (2013-02-02 16:28) [22]
> DevilDevil © (02.02.13 16:23) [21]
> есть ли на данный момент "парсер", который сразу работает
> с твоими внутренними данными ? таки нет. Даже XML-Binding
> генерирует свою структуру. Которая крайне не оптимальна
> по производительности
на Делфи свет клином не сошелся, вообще это не лучший язык для распарсивания чего-либо, по крайней мере, нет специальной заточки под это.
← →
DevilDevil © (2013-02-02 16:33) [23]> Eraser © (02.02.13 16:28) [22]
всё правильно
на С++ рвёт всех и вся PugiXML
но он DOM
кстати появился ещё AsmXML, который выдаёт ещё лучшую производительность
Ну и потом я на Delphi имею очень хорошие скорости парсинга и генерации XML. Если умеешь пользоваться Delphi по умному - то проблем с производительностью обычно не бывает
← →
Pavia © (2013-02-02 16:53) [24]
> описывать всё самому тоже не придётся, это сделает утилита
> XSD --> pas
И XSD она сама опишет?
> генератор изучать не придётся. Юзать только структуры и
> константы.
А структуры и константы изучать не надо?
← →
DevilDevil © (2013-02-02 17:04) [25]> И XSD она сама опишет?
ну для серьёзных XML (на которые в первую очередь ориентрирован парсер) всегда есть XSD.
потом есть решения, которые по имеющемуся XML сформируют схему. Я конечно не очень такому подходу доверяю, но это во многом выход. В конце концов в случае чего можно подкорректировать схему и перегенерировать парсер
> А структуры и константы изучать не надо?
Структуры соответствуют элементам в XSD. Константы тоже
← →
DevilDevil © (2013-02-02 21:50) [26]Таки очень нехватает человека, который разберётся в XSD схемах (и желательно разработает часть утилиты). Говорят в C# (.NET) есть какой-то интерфейс для работы с XSD
← →
Узурап (2013-02-03 03:48) [27]Удалено модератором
← →
Узурап (2013-02-03 03:48) [28]Удалено модератором
← →
Узурап (2013-02-03 03:49) [29]Удалено модератором
← →
DevilDevil © (2013-02-03 04:00) [30]Удалено модератором
← →
луеьфк (2013-02-03 09:51) [31]Удалено модератором
Примечание: Выражения выбираем
← →
DevilDevil © (2013-02-03 10:19) [32]для того чтобы понять, нужно как минимум знать:
1) что такое XML
2) как парсится XML
3) что хранится в XSD
4) почему приведённый мой код идентификации одной из 6 констант быстрее иных подходов
← →
Медвежонок Пятачок © (2013-02-04 09:45) [33]Только вместо готовых структур, констант и мегабыстрого парсера - ты возьмёшь стандартный парсер, и будешь для каждого узла и атрибута прописывать свою обработку со своим приведением типов.
А что если я возьму его, но не буду для каждого узла и атрибута прописывать свою обработку со своим приведением типа? И при этом все читается, и схема не нужна.
/* что давно и происходит на самом деле */
← →
sniknik © (2013-02-04 10:14) [34]> А структуры и константы изучать не надо?
http://delphimaster.net/view/15-1359703096/
Закон дырявых абстракций означает, к сожалению, что абстракции не так сильно упрощают нашу жизнь, как хотелось бы. Если я обучаю программистов C++, было бы здорово, если бы мне не нужно было рассказывать им про char* и арифметику указателей, а можно было сразу перейти к строкам из стандартной библиотеки темплейтов. Но в один прекрасный день они напишут "foo"+"bar", и возникнут странные проблемы, а мне придётся всё равно объяснить им, что такое char*. Или они попытаются вызвать функцию Windows с параметром типа LPTSTR и не смогут, пока не выучат char* и указатели и Юникод и wchar_t и хедерные файлы TCHAR — все то, что просвечивает через дырки в абстракциях.
и т.д.
изучать что-нибудь придется все одно.
ИМХО, лучше изучать первоисточник, и может чуть дольше, но делать правильно, с пониманием, чем тратить время на "поделку", и ладно, после основное сделать быстро, но в итоге в десять раз больше времени тратить на поиски "чудес".
← →
DevilDevil © (2013-02-04 11:50) [35]> Медвежонок Пятачок © (04.02.13 09:45) [33]
> sniknik © (04.02.13 10:14) [34]
Зависит от того, чего вы хотите
Вот я когда говорю о распарсивании XML вспоминаю многомегабайтные Excel-документы, которые если обрабатывать - то делать это нужно с максимальной скоростью. Есть один отчёт, выдаваемый Oracle - он весит 680Мб. И распарсить его я могу несколькими способами:
1) воспользоваться стандартным DOM-парсером типа MS XML. В этом случае софтина, использующая такой отчёт ляжет. MS XML мегамедленный и жрёт очень много памяти
2) воспользоваться альтернативным DOM-парсером. Это может быть и полюбившийся многим PugiXML, и другой интересный парсер AsmXML, и мой личный производительный DOM-парсер (вообще у меня уже есть пара реализаций парсер). В этом случае расход памяти будет около 680Мб + служебная информация... В итоге 1гб памяти только на то, чтобы иметь доступ к данным документа.
3) можно воспользоваться SAX-парсером. В этом случае не будет потрачено дополнительной памяти, но все приведения типов и отслеживания какой атрибут к какому элементу относится - придётся делать вручную
4) можно выжать производительность, если воспользоваться не SAX-парсером, а моим низкоуровневым парсером FastXmlReader (как я уже говорил - у меня есть несколько своих реализаций парсеров, одна лучше другой). В этом случае элемент представляется именем, значением и списком атрибутов. В целом можно вручную более удачно в плане производительности обработать элементы и атрибуты. Кроме того в SAX строка обычно оканчивается нулём, или не дай бог создаётся Heap-экземпляр строки (string например). А в моей реализации строка это указатель и длинна. Поэтому распознавание имени элемента и атрибута можно сделать методом, описанным в самом первом сообщении.
5) ну и наконец можно воспользоваться теоретическим SAX-парсером проекта ApolloXML. В этом случае вообще не нужно будет возиться с именами элементов и атрибутов - всё уже будет представлено константами и полями структур. При этом будет минимальное потребление памяти, и колоссальная скорость. Потому что парсер будет специально заточен под конкретные данные XML, а не универсальные, как это бывает в других парсерах
Я вообще не вижу преимуществ других парсеров над предложенным мной. Ну разве что DOM. Но опять таки, как я уже озвучил, DOM-модель можно организовать на основе этого парсера. И получится что-то типа XML-Binding, только только без строк в качестве имён и значений атрибутов
← →
Медвежонок Пятачок © (2013-02-04 11:55) [36]Я вообще не вижу преимуществ других парсеров над предложенным мной.
Зато я вижу.
Они (другие) есть, а твоего (наилучшего) еще нет.
← →
DevilDevil © (2013-02-04 12:47) [37]> Медвежонок Пятачок © (04.02.13 11:55) [36]
кто виноват и что делать ?
← →
Sergey Masloff (2013-02-04 14:24) [38]DevilDevil © (04.02.13 11:50) [35]
>Есть один отчёт, выдаваемый Oracle - он весит 680Мб. И распарсить его я >могу несколькими способами:
>1) воспользоваться стандартным DOM-парсером типа MS XML. В этом >случае софтина, использующая такой отчёт ляжет. MS XML мегамедленный >и жрёт очень много памяти
MS XML с версии 3.2 если не ошибаюсь, с 4 - точно имеет не только DOM но и SAX парсер. Файлы размером такого порядка разбираются с приемлемой скоростью. По крайней мере у меня узкое место не разбор при работе с этими файлами.
← →
DevilDevil © (2013-02-04 14:58) [39]> MS XML с версии 3.2 если не ошибаюсь, с 4 - точно имеет
> не только DOM но и SAX парсер.
я знаю, что есть
его можно отнести к пункту "3"
для меня вопрос "приемлемости" не совсем корректный. Я делю задачи на простые (управляющие) и ресурсоёмкие. Часто бывает вообще без разницы каким средством воспользоваться, лишь бы попроще. А если предполагается обрабатывать большие объёмы данных - то лучше покопаться с оптимизациями. В целом у меня трепетное отношение к пользователю. Я считаю для пользователя огромная разница: 3 секунды ждать или 10
Почему я заострил своё внимание на XML - наверное потому, что для меня разбор XML - одно из узких мест. Видимо остальные моменты работают быстро. Если говорить конечно о разборе большого объёма данных
К слову. Тестировали мы в своё время парсеры. Было 40Мб XML документа, который описывает один лист Excel-я, XML взят из внутренностей *.xlsx . Программа должна была подсчитать количество элементов, атрибутов и "значений элементов" в документе. 2086127 элемента, 2629448 атрибута, 882007 значений.
Так вот Expat справился за 1,100 мск, RapidXml за 390 мск, PugiXML за 290 мск, мой FastXmlReader за 230 мск; а SAX решение от Microsoft выполнялось 13 секунд! Мой конечно был быстрее, но он не делал текстовых преобразований, а RapidXml и PugiXML - это вообще DOM.
Но это тесты на быстрых современных машинах. Для старых четвёртых пентиумов надо умножать время в разы. И потом если мы говорим о 680Мб то надо умножать на 17 (680/40)
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2013.06.16;
Скачать: [xml.tar.bz2];
Память: 0.69 MB
Время: 0.004 c