performance serialization protocol-buffers asn.1

performance - ¿Cómo se compara el Buffers de Protocolo de Google con ASN.1?



serialization protocol-buffers (3)

Ha pasado mucho tiempo desde que realicé cualquier trabajo de ASN.1, pero es probable que el tamaño dependa de los detalles de sus tipos y datos reales.

Recomiendo encarecidamente que prototipos ambos y poner algunos datos reales para comparar.

Si su búfer de protocolo contiene tipos primitivos repetidos, debería buscar la fuente más reciente en Subversion para Buffers de Protocolo: ahora se pueden representar en un formato "empacado" que es mucho más eficiente en términos de espacio. (Mi puerto C # acaba de alcanzar esta característica, en algún momento de la semana pasada).

¿Cuáles son las diferencias más notorias entre Google Protocol Buffers y ASN.1 (con codificación PER)? Para mi proyecto, el problema más importante es el tamaño de los datos serializados. ¿Alguien ha hecho comparaciones de tamaño de datos entre los dos?


Si usa ASN.1 con PER no alineado y define sus tipos de datos utilizando las restricciones apropiadas (por ejemplo, especificando límites inferiores / superiores para enteros, límites superiores para la longitud de listas, etc.), sus codificaciones serán muy compactas. No habrá desperdicio de bits para cosas como la alineación o el relleno entre los campos, y cada campo será codificado en el número mínimo de bits necesarios para mantener su rango permitido de valores. Por ejemplo, un campo de tipo INTEGER (1..8) se codificará en 3 bits (1 = ''000'', 2 = ''001'', ..., 8 = ''111''); y una OPCIÓN con cuatro alternativas ocupará 2 bits (que indica la alternativa elegida) más los bits ocupados por la alternativa elegida. ASN.1 tiene muchas otras características interesantes que se han utilizado con éxito en muchos estándares publicados. Un ejemplo es el marcador de extensión ("..."), que cuando se aplica a SEQUENCE, CHOICE, ENUMERATED y a otros tipos, permite la compatibilidad hacia adelante y hacia atrás entre los puntos finales que implementan diferentes versiones de la especificación.


Cuando el tamaño del mensaje empaquetado / codificado sea importante, también debe tener en cuenta el hecho de que protobuf no puede empaquetar campos repeated que no son de un primitive numeric type léalo para obtener más información.

Este es un problema, por ejemplo, si tiene mensajes de ese tipo: (el comentario define el rango real de valores)

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; }

En caso de que tenga una longitud de matriz de, por ejemplo, 32, de lo que resultaría en un tamaño de mensaje empaquetado de aproximadamente 250 a 450 bytes con protobuf, dependiendo de qué valores contenga la matriz. Esto puede incluso aumentar a más de 1000 bytes en caso de que utilice el rango completo de 32 bits o en caso de que utilice int32 lugar de sint32 y tenga valores negativos.

El blob de datos brutos (suponiendo que z se puede definir como valor int16 ) solo consumiría 320 bytes y, por lo tanto, el mensaje ASN.1 siempre es menor que 320 bytes, ya que los valores máximos no son 32bit sino 19bit (x, y) y 15 bits (z).

El tamaño del mensaje protobuf se puede optimizar con esta definición de mensaje:

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; }

lo que da como resultado tamaños de mensaje entre aproximadamente 100 bytes (todos los valores son ceros), 300 bytes (valores en el rango máximo) y 500 bytes (todos los valores son valores altos de 32 bits).