Как буферы протокола Google сравниваются с ASN.Один

каковы наиболее заметные различия между буферами протокола Google и ASN.1 (с каждой кодировкой)? Для моего проекта наиболее важной проблемой является размер сериализованных данных. Кто-нибудь проводил сравнение размеров данных между ними?

3 ответов


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

Я сильно рекомендуем вам прототип и поместить некоторые реальные данные для сравнения.

Если ваш буфер протокола будет содержать повторяющиеся примитивные типы, вы должны посмотреть на последний источник в Subversion для буферов протокола - теперь они могут быть представлены в "упакованном" формате, который намного больше космос-эффективный. (Мой порт C# имеет просто догнал эту функцию, некоторое время на прошлой неделе.)


Если вы используете ASN.1 с Unaligned PER и определите свои типы данных, используя соответствующие ограничения (например, указав нижние/верхние границы для целых чисел, верхние границы для длины списков и т. д.).), ваши кодировки будут очень компактными. Там не будет бит впустую для таких вещей, как выравнивание или заполнение между полями, и каждое поле будет закодировано в минимальном количестве битов, необходимых для хранения его допустимого диапазона значений. Например, поле типа INTEGER (1..8) будет закодирован в 3 битах (1='000', 2='001', ..., 8='111'); и выбор с четырьмя альтернативами будет занимать 2 бита (с указанием выбранной альтернативы) плюс биты, занятые выбранной альтернативой. АСН.1 имеет много других интересных особенностей, которые были успешно использованы во многих опубликованных стандартов. Примером может служить маркер расширения ("..."), который при применении к последовательности, выбору, перечислению и другим типам обеспечивает обратную и прямую совместимость между конечными точками, реализующими разные версии спецификации.


когда размер упакованного / закодированного сообщения важен, вы также должны отметить тот факт, что protobuf не может упаковать repeated поля, которые не являются primitive numeric type, читать это для получения дополнительной информации.

это вопрос, например, если у вас есть сообщения такого типа: (комментарий определяет фактический диапазон значений)

message P{
    required sint32 x = 1; // -0x1ffff  to  0x20000
    required sint32 y = 2; // -0x1ffff  to  0x20000
    required sint32 z = 3; // -0x319c  to   0x3200
}
message Array{
    repeated P ps = 1;
    optional uint32 somemoredata = 2;
}

в случае, если у вас есть длина массива, например, 32, чем вы приведете к размеру упакованного сообщения приблизительно 250 до 450 байт с protobuf, в зависимости от того, какие значения фактически содержит массив. Это может даже увеличиться до более чем 1000 байт, если вы используете полный 32-битный диапазон или в случае, если вы используете int32 вместо sint32 и имеют отрицательные значения.

необработанный blob данных (предполагая, что z можно определить как int16 значение) будет потреблять только 320 байт и, следовательно,ASN.1 сообщении всегда меньше 320 байт, так как максимальные значения на самом деле не 32bit, но 19bit (x, y) и 15bit (z).

размер сообщения protobuf можно оптимизировать с помощью этого определения сообщения:

message Ps{
    repeated sint32 xs = 1 [packed=true];
    repeated sint32 ys = 2 [packed=true];
    repeated sint32 zs = 3 [packed=true];
}
message Array{
    required Ps ps = 1;
    optional uint32 somemoredata = 2;
}

что приводит к размерам сообщений между приблизительно 100 байтами (все значения-нули), 300 байтами (значения в диапазоне max) и 500 байтами (все значения-высокие значения 32bit).