Здравствуйте, c-smile, Вы писали:
CS>Ротом ея стали величать dbRaima.
Я сразу понял, что продукт так уже не называется, так как ссылок не было, но пару раз попадалось фамилия создателя Raima...
"Man feed machine
Machine feed man"
Peter Gabriel — OVO — The Tower That Ate People
Здравствуйте, c-smile, Вы писали:
CS>Мой вариант отвечает на вопросы "что и как" (или "каким образом" т.е. допускает некую метаинформацию) CS>Твой вариант отвечает только на "что" насколько я пока вижу (т.е. я могу ошибаться).
Правильно понимаешь. На вопрос как отвечает реализация архива, потому что packed_int, zipped_int и проч. это очень сильно зависит от архива. Ведь в том же XML никаких packed и zipped не будет, зато будет decimal и hexadecimal. А если потом появиться ещё один архив со своими вариантами хранения, то придётся переписывать класс?
Вот как я всё вижу — есть три объекта: класс, архив, поток.
В классе описываются данные
В архиве формат хранения данных
В потоке место хранения данных
Всё отделено друг от друга и взаимозаменяемо. К любому архиву можно прицепить любой поток, любой класс сериализовать в любой архив.
Ты же предлагаешь класс и архив сделать взаимосвязанными. Какие у этого плюсы я как раз понять не могу.
Здравствуйте, adontz, Вы писали:
A>Вот как я всё вижу — есть три объекта: класс, архив, поток. A>В классе описываются данные A>В архиве формат хранения данных A>В потоке место хранения данных A>Всё отделено друг от друга и взаимозаменяемо. К любому архиву можно прицепить любой поток, любой класс сериализовать в любой архив. A>Ты же предлагаешь класс и архив сделать взаимосвязанными. Какие у этого плюсы я как раз понять не могу.
Да! Ну и собственно в чём суть. Если тебе просто писать-читать и лишь бы работало, то функции сериализации можно нагенерировать и забыть о них, а если нужен особый формат, зависящий от архива (использующий особенности архива), то пиши функции сериализации вручную. И то скорее всего не все, ведь однажды написав сериализацию молекулы с использованием packed_int сериализацию вектора молекул уже можно сгенерировать (подумаешь, поле length не будет сжато ) и тем самым съекономить себе время и нервы.
Вот и пример родился. результаты автоматической и ручной сериализации строки в XML
// автоматически
<string>
<length>5</length>
<data>Hello</data>
</string>
// вручную, потому что нужен был именно такой формат
<string length="5" data="Hello"/>
Тут другой вопрос — А что если я хочу использовать автоматически сгенерированную сериализацию при передаче по сети и мою при записи в файл? Нет проблем!
Наследуем все архивы от одного класса archive_base. Автоматически сгенерированный сериализатор принимает параметр как раз типа archive_base. Если archive_xml унаследован от archive_base, то указав ручному сериализатору в качестве параметра archive_xml мы и получим то, что хотели. А вот и пример
/*
Это стандартная функция (скажем сгенерированная автоматически,
хотя на самом деле такое не может быть сгенерированно
потому что здесь вызовы методов.
Я просто поясняю как работает сериализация под конкретный архив)
*/void serialize_in(archive_base & archive, string & item)
{
archive.scope_begin("string");
archive.scope_begin("length");
archive.value_set("length", item.size());
archive.scope_end("length");
archive.scope_begin("data");
archive.value_set("data", item.c_str());
archive.scope_end("data");
archive.scope_end("string");
}
/*
А это написано ручками. Методов attribute_set/attribute_get в других архивах нет.
*/void serialize_in(archive_xml & archive, string & item)
{
archive.scope_begin("string");
archive.attribute_set("length", item.size());
archive.attribute_set("data", item.c_str());
archive.scope_end("string");
}
Компилятор сам выберет нашу функцию для сериализации в XML и сгенерированную для сериализации в другие архивы.
Здравствуйте, adontz, Вы писали:
A>А вот это как раз не факт. Если использовать метки полей, а не версии, то скорость всегда будет одинаковая.
По поводу скорости. То что структуры подлежащие сериализации простые и их мало не значит что записей будет мало.
Наоборот : где вы видели маленькие интегральные микросхемы ?
Я скажу проще — если на каждый прямоугольник мы поимеем virtual calls по количеству полей — это конец
SD>и чтобы код который использует сериализуемый тип автоматом подхватывал новую версию после изменения M_DEFAULT_VERSION и перекомпиляции а для утилиты преобразования V0001 -> V0002 были видны оба определения и там можна было руками "решить" проблему изменений. А когда старых данных точно не останется можно почистить старые версии структуры из исходных текстов и сохранить на память экзешник утилиты преобразования на всякий пожарный
повторю ХАЧУ УТИЛИТУ НАКАТА СХЕМЫ. Чтобы автоматом генерилась 1 раз
типа как шаблон <V0001, V0002>
и руками можно было указать ОДИН раз как преобразовывать.
A>Ты себе представляешь исходник в котором кроме новой версии класса все старые версии? Брррр!
Вас волнуют лишние определения версий структур ?
Они же кушать не просят. ни во что не компилируются и положить их на дно хидера
после коммента так никто и не увидит
А меня волнует поддержка версий. Я видел во что это превращается после того как она размазывается по многим файлам реализации
Эти SWITCH это есть ОЧЕНЬ ПЛОХО
Причем версии это неизбежно тк каждый сбежавший к клиентам экзешник это навсегда.
Y>это не бррр, это объективная реальность, и панацеи пока увы нет
Здравствуйте, SleepyDrago, Вы писали:
SD>Я скажу проще — если на каждый прямоугольник мы поимеем virtual calls по количеству полей — это конец
Стоп-стоп-стоп. Есть некоторая связь между рашряемостью и эффективностью.
Я собираюсь создать расширяемую систему и конечно я при этом вынужден буду в какой-то степени пожертвовать эффективностью.
Моя основная идея, это автоматизировать создание механизмов сериализации. Конечно, я не хочу наплодить неповоротливых монстров, но от виртуальных функций не убежать.
Если вы генерируете для некоторого RECT сериализацию автоматически, то получите скажем 14 вызов виртуальных функций.
В тоже время, ничто вам не мешает описать функцию сериализации RECT вручную и получить скажем 6 вызов. И одновременно с этим можно продолжать использовать автогенерацию для других классов.
Вообще боязнь виртуальных функций не имеет оснований. по сравнению со скоростью записи в файл или 100Мбит сокет это пустяки. Мы же не просто так её вызываем. Имеет место некоторый ввод-вывод.
Здравствуйте, adontz, Вы писали:
A>Здравствуйте, McSeem2, Вы писали:
A>В таком случае двоичный формат это вообще не очень удачная идея.
Бинарный вариант очень даже удачная идея, когда не надо экспортировать данные. А если надо, например, питону скормить, то тут уже лучше XML юзать. В любом случае хоца чтобы была возможность выбора...
MS>>Вторая мысть — IMHO (IMHO!) негоже писать значения базовых типов в XML content. MS>>Но, это лишь мое мнение, что так и проще и в то же время, как-то строже.
A>Тут есть другой момент. Я хотел позволять читать уже существубщие XML с уже предопределённой структурой, просто создав соответствующую XML (более или менее) структуру данных. Твой подход имеет свои плюсы, но мы в результате используем лишь подмножество XML, что ИМХО не есть хорошо.
Есть один выход: предоставить программисту возможность выбора как серилизовать данные. Я вот сейчас использую серилизацию от Андрея Мартынова. Все удобно, тока приходится напильником править много чего.
... << RSDN@Home 1.1.4 beta 3 rev. 241>>
"Бог не терпит голой сингулярности" -- Роджер Пенроуз
Здравствуйте, adontz, Вы писали:
A>Вообще боязнь виртуальных функций не имеет оснований. по сравнению со скоростью записи в файл или 100Мбит сокет это пустяки. Мы же не просто так её вызываем. Имеет место некоторый ввод-вывод.
ну не знаю как тут можно сравнивать, ведь запись в файл происходит для закешированого фрагмента, а не каждый раз при сериализации определенной переменной.
Здравствуйте, adontz, Вы писали:
A>Что скажете? Насколько это на ваш взгляд будет удобно/востребованно?
Я не понимаю одной вещи: почему всю сериализацию нельзя свести к дополнителной библиотеке/скрипту, запускающейся перед компиляцией? Зачем нужны все эти извращения с дополнительными полями, макросами и прочей чепухой?
Но я категорически против того, чтобы помечать этот класс некой крокозяблой и таким образом изначально ставить его в зависимость от какой-то там левой сериализации (хоть своей, хоть чужой — не важно).
Здравствуйте, yxiie, Вы писали:
Y>ну не знаю как тут можно сравнивать, ведь запись в файл происходит для закешированого фрагмента, а не каждый раз при сериализации определенной переменной.
Для малых объёмов сравнения действительно бессмысленны и не нужны, для больших же допустимы. Если пишеться 100 байт, то пусть хоть 100 виртуальных функций вызовется — это мелочь.
Если же пишется 30 Мб, то тут время записи скажем секунда или две, в то время как время обработки такой информации процессором доли секунды. Сериализацию по любому будет тормозить система ввода вывода, так что что-то оптимизировать на уровне процессора практически бесполезно, зато заметно увеличить скороть может уменьшение объёмов данных.
Здравствуйте, Olegator, Вы писали:
O>Я не понимаю одной вещи: почему всю сериализацию нельзя свести к дополнителной библиотеке/скрипту, запускающейся перед компиляцией? Зачем нужны все эти извращения с дополнительными полями, макросами и прочей чепухой?
Потому что я не хочу заметно увеличивать скорость компиляции. Для этого я получаю информацию о типах от самого компилятора. Для этого файл сперва надо скомпилировать, а уже потом обработать моей утилиткой, но сделать это надо до компоновки.
O>Re[5]: Философское предложение
O>Но я категорически против того, чтобы помечать этот класс некой крокозяблой и таким образом изначально ставить его в зависимость от какой-то там левой сериализации (хоть своей, хоть чужой — не важно).
O>Золотые слова!
А кто сказал, что так нельзя будет?
O>Что скажете?
Жутко не гибко Формат, место хранения, всё задаётся на этапе компиляции.
Здравствуйте, Olegator, Вы писали:
O>Почему? Что в этом плохого, и как бы Вы это сделали, если б хотели?
Вы предлагаете написать некоторый парсер Си++ кода. Вот и вопрос, а оно надо парсить один итот же файл два раза (компилятор +утилитка)?
ОК, заменили макрос на вызов функции, а функцию сгенерировали в специальном файле. Но см. ниже.
A>>Жутко не гибко Формат, место хранения, всё задаётся на этапе компиляции.
O>Соответственно значения iSelectedType и sSelectedOutput менять на этапе исполнения.
Кроме того, вы предлагаете генерировать сериализацию по факту её использования, а я по факту объявления типа.
Не уверен (не берусь судить но всё же), что эти подходы будут иметь один результат
Вобщем я не то чтобы против, но есть некоторые минусы (написание своего парсера — плохо как по времени исполнения, так и по времени написания), а особых плюсов я как-то пока не вижу
Здравствуйте, adontz, Вы писали:
A>Потому что я не хочу заметно увеличивать скорость компиляции. Для этого я получаю информацию о типах от самого компилятора. Для этого файл сперва надо скомпилировать, а уже потом обработать моей утилиткой, но сделать это надо до компоновки.
какой ужас! и что, это только для VC будет работать?
Здравствуйте, yxiie, Вы писали:
Y>какой ужас! и что, это только для VC будет работать?
Ну зачем же так? Просто в VC это будет работать так как я описал, я для GCC либо действительно два раза парсить, либо патчить сам GCC. У уже глядел в сторону gcc_xml (НЕ понравился) и развивающегося проекта introspector (на sourceforge.net).
В крайнем случае можно действительно заюзать boost.spirit
Для меня основной Си++ компилятор это VC (в данный момент пользую 7.1) и если он оказался так замечательно расширяем, то почему бы мне эти не воспользоваться?
В любом случае автогенератор разбивается на три модуля.
получение метаинформации для конкретной единицы компиляции
слияние метаинформация для всех единиц проекта (удаление дубликатов)
Здравствуйте, c-smile, Вы писали:
CS>Т.е. задача сводится к разаработке языка и набору функций read/write у которых первый параметр это schema_difinition* psd
CS>Типа того.
C# ? Описываешь тип на шарпе, потом с помощью рефлекшена генеришь то, что нужно.