повысить сериализацию по сравнению с буферами протокола Google?[закрыто]

StackOverflow https://stackoverflow.com/questions/1061169

Вопрос

Кто-нибудь, имеющий опыт работы с этими библиотеками, может прокомментировать, какую из них они предпочитают?Были ли какие-либо различия в производительности или трудности в использовании?

Это было полезно?

Решение

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

При использовании boost::serialization вы сначала пишете свои собственные структуры/классы, а затем добавляете методы архивирования, но у вас все равно остаются несколько довольно «тонких» классов, которые можно использовать как члены данных, наследовать и т. д.

При использовании буферов протокола объем кода, генерируемого даже для простой структуры, довольно значителен, а сгенерированные структуры и код больше предназначены для работы, и вы используете функциональность буферов протокола для транспортировки данных в ваши собственные внутренние структуры и из них. .

Другие советы

Я использую Boost Serialization в течение долгого времени и просто копался в буферах протоколов, и я думаю, что у них разные цели.BS (не ожидал этого) сохраняет ваши объекты C++ в поток, тогда как PB — это формат обмена, который вы читаете в/из.

Модель данных PB намного проще:вы получаете все виды целых чисел и чисел с плавающей запятой, строки, массивы, базовую структуру, и это почти все.BS позволяет вам напрямую сохранять все ваши объекты за один шаг.

Это означает, что с BS вы получаете больше данных по сети, но вам не нужно перестраивать всю структуру ваших объектов, тогда как буферы протоколов более компактны, но после чтения архива необходимо выполнить больше работы.Как следует из названия, один предназначен для протоколов (независимая от языка, эффективная передача данных), другой — для сериализации (легкое сохранение объектов).

Итак, что для вас важнее:скорость/эффективность использования пространства или чистый код?

Есть еще несколько проблем, связанных с boost.serialization, которые я добавлю к этому.Предостережение:У меня нет никакого непосредственного опыта работы с буферами протоколов, кроме просмотра документации.

Обратите внимание: хотя я считаю, что boost и boost.serialization отлично справляются со своими задачами, я пришел к выводу, что форматы архивов по умолчанию, которые он поставляется, не являются лучшим выбором для проводного формата.

Важно различать версии твой класс (как упоминалось в других ответах, boost.serialization имеет некоторую поддержку управления версиями данных) и совместимость между различными версиями библиотека сериализации.

Новые версии boost.serialization может не создавать архивы, которые можно десериализовать в более старых версиях.. (обратное неверно:более новые версии всегда предназначены для десериализации архивов, созданных более старыми версиями).Это привело нас к следующим проблемам:

  • И наше клиентское, и серверное программное обеспечение создают сериализованные объекты, которые потребляет другое, поэтому мы можем перейти на более новую версию boost.serialization только в том случае, если мы синхронно обновим и клиент, и сервер.(Это довольно сложная задача в среде, где вы не имеете полного контроля над своими клиентами).
  • Boost поставляется в виде одной большой библиотеки с общими частями, а также кодом сериализации и другими частями библиотеки Boost (например,shared_ptr) может использоваться в том же файле, я не могу обновить любой части boost, потому что я не могу обновить boost.serialization.Я не уверен, возможно ли/безопасно/разумно попытаться связать несколько версий boost в один исполняемый файл, или есть ли у нас бюджет/энергия для рефакторинга битов, которые должны остаться в более старой версии boost, в отдельную исполняемый файл (в нашем случае DLL).
  • Старая версия boost, на которой мы остановились, не поддерживает последнюю версию используемого нами компилятора, поэтому мы также остановились на старой версии компилятора.

Google, кажется, на самом деле опубликовать формат провода буферов протокола, и Википедия описывает их как вперед-совместимый, обратно-совместимый (хотя я думаю, что Википедия имеет в виду управление версиями данных, а не управление версиями библиотеки буферов протокола).Хотя ни один из этих способов не является гарантией прямой совместимости, мне кажется, это более убедительный признак.

В итоге, Я бы предпочел известный, опубликованный формат телепередачи. например, буферы протоколов, когда у меня нет возможности синхронно обновлять клиент и сервер.

Сноска:бесстыдная вилка для соответствующий ответ мной.

Ускорить сериализацию

  • — библиотека для записи данных в поток.
  • не сжимает данные.
  • не поддерживает автоматическое управление версиями данных.
  • поддерживает контейнеры STL.
  • свойства записываемых данных зависят от выбранных потоков (например,с порядком байтов, сжатый).

Буферы протоколов

  • генерирует код из описания интерфейса (по умолчанию поддерживает C++, Python и Java).C, C# и другие сторонние производители).
  • опционально сжимает данные.
  • автоматически обрабатывает версии данных.
  • обрабатывает обмен байтами между платформами.
  • не поддерживает контейнеры STL.

Сериализация Boost — это библиотека для преобразования объекта в сериализованный поток данных.Буферы протокола делают то же самое, но также выполняют за вас другую работу (например, управление версиями и замену байтов).Сериализация Boost проще для «небольших простых задач».Буферы протоколов, вероятно, лучше подходят для «более крупной инфраструктуры».

РЕДАКТИРОВАТЬ: 24-11-10:Добавлено «автоматически» в управление версиями BS.

У меня нет опыта сериализации повышения, но я использовал буферы протокола.Мне очень нравятся буферы протоколов.Имейте в виду следующее (я говорю это с нет знаний повышения).

  • Буферы протоколов очень эффективны, поэтому я не представлять себе это серьезная проблема против.способствовать росту.
  • Буферы протоколов предоставляют промежуточное представление, которое работает с другими языками (Python и Java...и многое другое в работе).Если вы знаете, что используете только C++, возможно, лучше использовать boost, но возможность использовать другие языки хороша.
  • Буферы протоколов больше похожи на контейнеры данных...нет объектно-ориентированного характера, такого как наследование.Подумайте о структуре того, что вы хотите сериализовать.
  • Буферы протоколов являются гибкими, поскольку вы можете добавлять «необязательные» поля.По сути, это означает, что вы можете изменить структуру буфера протокола, не нарушая совместимости.

Надеюсь это поможет.

boost.serialization просто нуждается в компиляторе C++ и дает вам некоторый синтаксический сахар, например

serialize_obj >> archive;
// ...
unserialize_obj << archive;

для сохранения и загрузки.Если C++ — единственный язык, который вы используете, вам следует серьезно подойти к boost.serialization.

Я быстро просмотрел буферы протокола Google.Судя по тому, что я вижу, я бы сказал, что это нельзя напрямую сравнивать с boost.serialization.Вам необходимо добавить компилятор файлов .proto в свою цепочку инструментов и поддерживать сами файлы .proto.API не интегрируется в C++, как это делает boost.serialization.

boost.serialization очень хорошо справляется со своей задачей:Для сериализации объектов C ++ :) OTOH APER-API, подобный буферам протокола Google, дает вам большую гибкость.

Поскольку до сих пор я использовал только boost.serialization, я не могу комментировать сравнение производительности.

Поправка к вышесказанному (думаю, это этот ответ) о сериализации Boost:

Это ДЕЙСТВИТЕЛЬНО позволяет поддерживать управление версиями данных.

Если вам нужно сжатие — используйте сжатый поток.

Может обрабатывать обмен байтами между платформами, поскольку кодировка может быть текстовой, двоичной или XML.

Я никогда ничего не реализовал с помощью библиотеки boost, но нашел, что protobuff от Google более продуман, а код намного чище и легче читается.Я бы посоветовал взглянуть на различные языки, с которыми вы хотите его использовать, прочитать код и документацию и принять решение.

Единственная трудность, с которой я столкнулся при работе с protobufs, заключалась в том, что они назвали очень часто используемую функцию в сгенерированном коде GetMessage(), что, конечно, конфликтует с макросом Win32 GetMessage.

Я все равно очень рекомендую protobufs.Они очень полезны.

Как и почти все в инженерном деле, мой ответ такой..."это зависит."

Обе технологии хорошо протестированы и проверены.Оба возьмут ваши данные и превратят их во что-то удобное для отправки куда-нибудь.Оба, вероятно, будут достаточно быстрыми, и если вы действительно считаете байт здесь или там, вы, вероятно, не будете довольны ни тем, ни другим (давайте посмотрим правде в глаза, оба созданных пакета будут представлять собой небольшую часть XML или JSON).

Для меня все сводится к рабочему процессу и к тому, нужно ли вам что-то кроме C++ на другом конце.

Если вы хотите сначала выяснить содержимое вашего сообщения и создаете систему с нуля, используйте буферы протокола.Вы можете думать о сообщении абстрактно, а затем автоматически генерировать код на любом языке, который вам нужен (сторонние плагины доступны практически для всего).Кроме того, я считаю, что совместная работа упрощается с помощью протокольных буферов.Я просто отправляю файл .proto, и тогда другая команда получает четкое представление о том, какие данные передаются.Я им тоже ничего не навязываю.Если они хотят использовать Java, вперед!

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

Вы можете использовать ускоренную сериализацию в тесной связи с вашими «реальными» объектами домена и сериализовать полную иерархию объектов (наследование).Protobuf не поддерживает наследование, поэтому вам придется использовать агрегацию.Люди утверждают, что Protobuf следует использовать для DTO (объектов передачи данных), а не для самих объектов основного домена.Я использовал как boost::serialization, так и protobuf.Следует учитывать производительность boost::serialization, злак может быть альтернативой.

Я знаю, что это уже старый вопрос, но я решил добавить свои 2 пенса!

Благодаря boost вы получаете возможность написать проверку данных в ваших классах;это хорошо, потому что определение данных и проверки на достоверность находятся в одном месте.

С GPB лучшее, что вы можете сделать, — это оставлять комментарии в файле .proto и вопреки всякой надежде надеяться, что тот, кто его использует, прочитает его, обратит на него внимание и самостоятельно осуществит проверки достоверности.

Излишне говорить, что это маловероятно и ненадежно, если вы полагаетесь на то, что кто-то другой на другом конце сетевого потока сделает это с той же энергией, что и вы.Кроме того, если ограничения на достоверность изменятся, необходимо спланировать, скоординировать и внести несколько изменений в код.

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

==РЕДАКТИРОВАТЬ==

Я имею в виду следующее:

message Foo
{
    int32 bearing = 1;
}

Теперь кто скажет, каков действительный диапазон bearing является?Мы можем иметь

message Foo
{
    int32 bearing = 1;  // Valid between 0 and 359
}

Но это зависит от того, кто-то еще прочитает это и напишет для этого код.Например, если вы отредактируете его, и ограничение станет следующим:

message Foo
{
    int32 bearing = 1;  // Valid between -180 and +180
}

вы полностью зависите от всех, кто использовал этот .proto, обновляя свой код.Это ненадежно и дорого.

По крайней мере, с помощью сериализации Boost вы распространяете один класс C++, и в него могут быть встроены проверки достоверности данных.Если эти ограничения изменятся, никому больше не нужно будет делать никакой работы, кроме как убедиться, что они используют ту же версию исходного кода, что и вы.

Альтернатива

Есть альтернатива:АСН.1.Это древний вариант, но в нем есть несколько действительно полезных вещей:

Foo ::= SEQUENCE
{
   bearing INTEGER (0..359)
}

Обратите внимание на ограничение.Поэтому всякий раз, когда кто-либо использует этот файл .asn и генерирует код, он в конечном итоге получает код, который автоматически проверяет это. bearing находится где-то между 0 и 359.Если вы обновите файл .asn,

Foo ::= SEQUENCE
{
   bearing INTEGER (-180..180)
}

все, что им нужно сделать, это перекомпилировать.Никаких других изменений кода не требуется.

Вы также можете сделать:

bearingMin INTEGER ::= 0
bearingMax INTEGER ::= 360

Foo ::= SEQUENCE
{
   bearing INTEGER (bearingMin..<bearingMax)
}

Обратите внимание <.Кроме того, в большинстве инструментов BearingMin и BearingMax могут отображаться как константы в сгенерированном коде.Это чрезвычайно полезно.

Ограничения могут быть весьма сложными:

Garr ::= INTEGER (0..10 | 25..32)

Посмотрите главу 13 в этом PDF;удивительно, что ты можешь сделать;

Массивы также могут быть ограничены:

Bar ::= SEQUENCE (SIZE(1..5)) OF Foo
Sna ::= SEQUENCE (SIZE(5)) OF Foo
Fee ::= SEQUENCE 
{
    boo SEQUENCE (SIZE(1..<6)) OF INTEGER (-180<..<180)
}

ASN.1 старомоден, но все еще активно развивается, широко используется (его часто использует ваш мобильный телефон) и гораздо более гибок, чем большинство других технологий сериализации.Единственный недостаток, который я вижу, это отсутствие достойного генератора кода для Python.Если вы используете C/C++, C#, Java, ADA, вам подойдет сочетание бесплатных (C/C++, ADA) и коммерческих (C/C++, C#, JAVA) инструментов.

Мне особенно нравится широкий выбор двоичных и текстовых форматов проводов.Это делает его чрезвычайно удобным в некоторых проектах.Список форматов проводов на данный момент включает в себя:

  • BER (двоичный)
  • PER (двоичный, выровненный и невыровненный.Это очень эффективно.Например, и INTEGER ограничен между 0 и 15 займет только 4 bits на проводе)
  • ООР
  • DER (еще один двоичный файл)
  • XML (также XER)
  • JSON (совершенно новый, поддержка инструментов все еще развивается)

плюс другие.

Обратите внимание на последние два?Да, вы можете определять структуры данных в ASN.1, генерировать код и отправлять/потреблять сообщения в XML и JSON.Неплохо для технологии, которая возникла еще в 1980-х годах.

Управление версиями осуществляется иначе, чем в GPB.Вы можете разрешить расширения:

Foo ::= SEQUENCE
{
   bearing INTEGER (-180..180),
   ...
}

Это означает, что позже я смогу добавить к Foo, и более старые системы, имеющие эту версию, все еще могут работать (но имеют доступ только к bearing поле).

Я очень высоко оцениваю ASN.1.С этим может быть сложно справиться (инструменты могут стоить денег, сгенерированный код не обязательно красив и т. д.).Но ограничения — это поистине фантастическая функция, которая снова и снова спасала меня от множества душевных болей.Заставляет разработчиков сильно ныть, когда кодеры/декодеры сообщают, что они сгенерировали пустые данные.

Другие ссылки:

Наблюдения

Чтобы поделиться данными:

  • Первые подходы к коду (например.Boost сериализация) ограничивает вас исходным языком (например,C++) или заставит вас выполнять много дополнительной работы на другом языке.
  • Сначала лучше использовать схему, но
    • Многие из них оставляют большие пробелы в договоре о разделе (т.е.никаких ограничений).ГПБ в этом плане раздражает, потому что в остальном он очень хорош.
    • Некоторые имеют ограничения (например,XSD, JSON), но имеют неоднородную поддержку инструментов.
    • Например, xsd.exe от Microsoft активно игнорирует ограничения в файлах xsd (оправдание MS действительно слабое).XSD хорош (с точки зрения ограничений), но если вы не можете доверять другому парню в использовании хорошего инструмента XSD, который применяет их для него / нее, тогда ценность XSD уменьшается.
    • С валидаторами JSON все в порядке, но они ничего не делают, чтобы помочь вам сформировать JSON, и не вызываются автоматически.Нет никакой гарантии, что кто-то, отправляющий вам сообщение JSON, пропустил его через валидатор.Вы должны не забыть проверить это самостоятельно.
    • Все инструменты ASN.1, похоже, реализуют проверку ограничений.

Так что для меня это делает ASN.1.Это тот вариант, который с наименьшей вероятностью приведет к ошибке кого-то другого, потому что он обладает правильными функциями и все инструменты которого, по-видимому, стремятся полностью реализовать эти функции, и он достаточно нейтральен к языку для большинства целей.

Честно говоря, если бы GPB добавил механизм ограничений, это было бы победителем.XSD близок, но инструменты почти всегда являются мусором.Если бы были достойные генераторы кода на других языках, схема JSON была бы довольно хороша.

Если в GPB были добавлены ограничения (примечание:это не изменит ни один из форматов проводов), я бы порекомендовал его всем практически для любых целей.Хотя uPER ASN.1 очень полезен для радиосвязи.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top