Когда важен размер упакованного / закодированного сообщения, вы должны также отметить тот факт, что 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
и имеете отрицательные значения.
Блок необработанных данных (при условии, что z можно определить как значение int16
) будет занимать только 320 байтов, и, таким образом, сообщение ASN.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-битными значениями).