Comments.blogs

А как вы работаете с xml?

19 мар 2007 10:18
0
(Текст записи скрыт. Показать...)
Интересно, как сейчас в разных компаниях обстоит дело с работой с xml форматом? Используете или нет? Если да, то какие средства для чтения\записи? Какие именно фичи из xml используется?
Есть мнение, что мы изобретали в очередной раз свой велосипед – хотелось бы это обсудить и понять, так ли это .
Вкратце про эволюцию работы с xml у нас в Лесте читай в блоге...


Началась наша работа с xml с парсера TinyXml. Достаточно удобный и простой парсер. Его просто подключить, просто использовать. Его минусы проявляются только когда появляются огромные xml файлы или когда надо работать с частями этих файлов, хранить subNodes и т.п. – тут начинаются тормоза и проблемы с памятью. Также проблемой являлось то, что не было типизации – в любую ноду можно было записать все, что угодно и только в момент загрузки можно было сконвертировать в нужный тип из строки.
Вот кусок такого файла:

<IconName value="DE_PC1000"/>
<Icon value="TL/Icon/Ammo/DE_PC1000"/>
<ExploPower value="150"/>
<IsBomb value="true"/>

Дальнейшим шагом было написание товарищем Corvax (http://www.dtf.ru/person/info.php?id=1212) системы классов, имеющих у нас кодовое имя SMCC. Это фактически был набор классов, которые хранили в себе данные из xml и умели загружаться и сохраняться в него. Всё на умных указателях. Работать стало удобнее за счет того, что нам нужно было строго ограниченное число типов данных внутри xml (object, string, int, float, bool, wstring, data). Вот кусок такого файла:

<object name = "Second_Turret_155_Yamato">
<integer name = "Country" value = "2"/>
<string name = "Type" value = "Gun"/>
<boolean name = "Production" value = "false"/>
<float name = "Weight" value = "177"/>
</object>

Вот работа с ним:


for (CompoundObject::ConstIterator i = turrets->begin(),
iend = turrets->end();
i != iend;
++i
)
{
std::string name = i->first; // "Second_Turret_155_Yamato"
ObjectAttribute turret = i->second;

IntegerAttibute attrCountryId = turret->get("Country");
int attrCountryId = attrCountryId->getValue();

std::string turretType = turret->getAs<TypeId::String>("Gun")->getValue();

bool production = safeGetValue(turret, "Production", false);

Attribute attrWeight = turret->get("Weight");
double weight = As<TypeId::Float>(attrWeight)->getValue();
}


Этот файл уже имеет типизацию, которую можно проверять и выдавать Exception, если тип неправильный.
Минусом первого варианта системы SMCC было то, что она была надстройкой над TinyXml и вся загрузка и сохранение велась через нее.
Дальнейшей оптимизацией было создание своего парсера xml для нашего формата. Он легковесный и работает в несколько раз быстрее TinyXml.
Следующей мыслью было то, что у нас строго ограниченный набор типов в xml, а значит можно сделать и бинарный формат. Сделали. Получили прирост скорости парсинга xml еще в несколько раз. Например, файл сэйва занимал 50mb в xml, старый парсинг и сохранение могли занимать 10 и более секунд, а новый отрабатывает менее, чем за секунду.
Ну и недавно дошли руки до загрузки xml с помощью Loading inplace. Это вообще максимально быстрый алгоритм. Работает за счет того, что число типов ограничено.
Естественно, все форматы грузятся любым загрузчиком. Даже Loading inplace грузит обычный xml, правда медленно, т.к. сначала надо распарсить всю структуру.
Также пришлось написать утилиту, конвертирующую форматы xml в разные виды, чтобы можно было бинарные форматы конвертировать в текстовый для просмотра и редактирования, но т.к. большинство xml экспортятся из maya или базы данных, то делать это приходится нечасто.

В итоге сейчас мы имеем систему работы с xml, сочетающую в себе как плюсы бинарных файлов, так и удобство текстового xml формата.
А у вас есть такой велосипед?
Отправлено 20.03.2007 в 15:35
Отвечает на сообщение 187091
0
Alexey Baskakov wrote:
>
> один из них (pugixml) - AFAIK самый быстрый из
> общедоступных. ну и плюс автор ptree сейчас пишет
> пятый, хочет pugixml обогнать.


:) имхо, быстрее нашего бинарного парсера он быть не может.

>
> А откуда такие большие файлы? в интересах
> распараллеливания работ и versioning 1 файл
> должен представлять 1 unit работы одного человека
> (с целью минимизировать конфликты SVN/CVS
> например)


по 50мб получались сэйвы. Там несколько десятков тысяч юнитов может быть.

> Ну вот эту прослойку (описание объектов и их
> структуры) можно будет не писать, так как она все
> равно уже есть на метауровне. А сгенерить по ней
> код, который будет заниматься сериализацией -
> проще простого. И никаких томрозов с компилянием
> навороченных C++ шаблонов.
>


похоже на то, что писал Сергей Захаров парой постов выше?

> Впрочем, у нас все равно приведенная работа с xml
> только в редакторе осталась.


аминь :)
Отправлено 20.03.2007 в 15:53
Отвечает на сообщение 187141
0
> :) имхо, быстрее нашего бинарного парсера он быть не может.

Эээ... Не понял. xml же - не бинарный формат. Есть конечно binary xml, но на него все забили.

> по 50мб получались сэйвы. Там несколько десятков тысяч юнитов может быть.


Не понимаю этой зацикленности - зачем сейвы делать в xml...
Да и 50000/10000=5 кб на юнит. Слишком много, не иначе вы туда вообще все данные скидываете, а не только runtime-defined отличия от прототипа юнита.

> похоже на то, что писал Сергей Захаров парой постов выше?

не видел.

UPDATE: увидел. не - совсем наоборот. отличается так же, как концепция генерации кода по UML от генерации кода в DSL.
Отправлено 20.03.2007 в 16:12
Отвечает на сообщение 187152
0
Alexey Baskakov wrote:
>
> > :) имхо, быстрее нашего бинарного парсера он
> быть не может.
>
> Эээ... Не понял. xml же - не бинарный формат.
> Есть конечно binary xml, но на него все забили.


Я же писал, что у нас свой велосипед :). Есть конвертер xml-binary-xml. Для быстрой загрузки и сохранения того, что надо.

>
> > по 50мб получались сэйвы. Там несколько
> десятков тысяч юнитов может быть.
>
> Да и 50000/10000=5 кб на юнит. Слишком много, не
> иначе вы туда вообще все данные скидываете, а не
> только runtime-defined отличия от прототипа
> юнита.


5 кб в xml - не так уж и много :). Там только меняющиеся данные. Кроме того, есть в игре не только юниты, но и другие сущности. Например, формации, которых тоже тысячи, АИ-приказы, которые могут быть у каждого юнита или формации и т.п. Короче, много информации надо сохранять.

> Не понимаю этой зацикленности - зачем сейвы
> делать в xml...


На самом же деле сэйвы в текстовом виде удобнее, чем в бинарном. Их проще расширять, проще читать, проще отлаживать вначале. В конце проекта на этапе мастера они превращаются в зло, т.к. тормозят и занимают много места :).
Поэтому перед мастером я сделал хитрый финт - самые частовстречающиеся объекты сохранил в xml в бинарном виде. Это сократило размер в несколько раз и ускорило загрузку также в несколько раз.
А у вас сэйв в каком виде?

>
> > похоже на то, что писал Сергей Захаров парой
> постов выше?
> не видел.
>
> UPDATE: увидел. не - совсем наоборот. отличается
> так же, как концепция генерации кода по UML от
> генерации кода в DSL.


пошел читать про DSL...
Отправлено 20.03.2007 в 16:21
Отвечает на сообщение 187161
0
> А у вас сэйв в каком виде?

Абстрактно - тупо в бинарь скидывается POD помеченных полей объектов. Конкретно (например, в гоночках) - вообще сейва почти нет :)

Если нужен был бы versioning у save/load - сделал бы метаданные по его бинарной структуре.
Oleg Fedorov  20.03.2007 16:36
Comments.blogs
Списки доступа
  • Подписчики [789]
Права доступа
У обсуждений в этой группе различные ограничения доступа.
Пользователи имеют персональные права доступа к обсуждениям.

Copyright © 2021 ООО "ДТФ.РУ". Все права защищены.

Воспроизведение материалов или их частей в любом виде и форме без письменного согласия запрещено.

Замечания и предложения отправляйте через форму обратной связи.

Пользовательское соглашение