Вопрос

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

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

Решение

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

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

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

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

Если вы используете ASN.1 с невыровненным значением PER и определяете свои типы данных, используя соответствующие ограничения (например, указывая нижние / верхние границы для целых чисел, верхние границы для длины списков и т.д.), ваши кодировки будут очень компактными.Никакие биты не будут потрачены впустую на такие вещи, как выравнивание или заполнение между полями, и каждое поле будет закодировано в минимальном количестве битов, необходимом для хранения его допустимого диапазона значений.Например, поле типа INTEGER (1..8) будет закодировано в 3 бита (1='000', 2='001', ..., 8='111');и ВЫБОР с четырьмя альтернативами будет занимать 2 бита (указывающий на выбранную альтернативу) плюс биты, занятые выбранной альтернативой.ASN.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, то в результате размер упакованного сообщения с protobuf составит примерно от 250 до 450 байт, в зависимости от того, какие значения на самом деле содержит массив.Это может даже увеличиться до более чем 1000 байт, если вы используете полный 32-битный диапазон или в случае, если вы используете int32 вместо того , чтобы sint32 и имеют отрицательные значения.

Большой двоичный объект необработанных данных (при условии, что z может быть определен как int16 значение) потребляло бы всего 320 байт и, таким образом, АСН.1 сообщение является всегда меньше 320 байт, поскольку максимальные значения на самом деле не 32 бита, а 19 бит (x, y) и 15 бит (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 байт (значения в максимальном диапазоне) и 500 байт (все значения имеют высокие 32-битные значения).

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