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


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

11 62

11 ответов:

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

с помощью Boost:: serialization вы сначала пишете свои собственные структуры/классы, а затем добавляете методы архивирования, но у вас все еще остаются некоторые довольно "тонкие" классы, которые можно использовать в качестве членов данных, унаследованных, что угодно.

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

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

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

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

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

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

обратите внимание, что пока я думаю наддув, и наддув.сериализация, отлично справляется с тем, что она делает, я пришел к выводу, что форматы архивов по умолчанию, с которыми она поставляется, не являются отличным выбором для формата wire.

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

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

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

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

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

сноска: бесстыдный штекер для обзоры ответа мной.

Буст Сериализация

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

Протокол Буферы

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

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

EDIT: 24-11-10: добавлено "автоматически" для управления версиями BS.

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

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

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

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

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

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

я быстро взглянул на буферы протокола google. Из того, что я вижу, я бы сказал, что это не напрямую сопоставимо с повышением.сериализация. Вы должны добавить компилятор для .прото файлы в вашей цепочке инструментов и поддерживать .прото-файлы сами по себе. API не интеграция в C++ как boost.сериализация делает.

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

Так как я использовал только boost.сериализация пока я не могу комментировать сравнение производительности.

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

Это позволяет поддерживать управление версиями данных.

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

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

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

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

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

Как и почти все в технике, мой ответ... - это зависит от обстоятельств."

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

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

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

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

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

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

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

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

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

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

= = EDIT==

я имею в виду вот что:

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
}

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

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

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

есть альтернатива: ASN.1. Это древний, но имеет некоторые очень, очень, удобно вещи:

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

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

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) инструментов.

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

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

плюс другие.

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

управление версиями выполняется по-разному для GPB. Вы можете разрешить для расширений:

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

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