Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.06.16;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.63 MB
Время: 0.009 c
15-1359807822
Дмитрий С
2013-02-02 16:23
2013.06.16
Стартовый бит rs232


15-1360137627
O'ShinW
2013-02-06 12:00
2013.06.16
Не получается логгировать ответы Апача.


15-1359713619
asdasd
2013-02-01 14:13
2013.06.16
win8 убрать черный квадрат с раб стола


15-1359237872
Rouse_
2013-01-27 02:04
2013.06.16
Перехват АПИ


11-1246026537
Nikfel
2009-06-26 18:28
2013.06.16
Как вставить строку в TkolMemo?