Pregunta

¿Cuáles son las diferencias más notable entre Google Protocol Buffers y ASN.1 (con PER-codificación)? Para mi proyecto el tema más imporante es el tamaño de los datos serializados. Alguien ha hecho ninguna comparación del tamaño de los datos entre los dos?

¿Fue útil?

Solución

Es un largo tiempo desde que he hecho ningún trabajo ASN.1, pero el tamaño es muy probable que dependen de los detalles de sus tipos y datos reales.

Me muy recomendar que prototipos de ambos y poner un poco de datos reales para comparar.

Si el búfer de protocolo contendría repetida tipos primitivos, se debe consultar la última fuente de Subversion para Protocol Buffers - que pueden ser representados en un formato de "lleno" ahora que es mucho más eficiente con el espacio. (Mi C # puerto tiene solo atrapados con esta característica, alguna vez la semana pasada.)

Otros consejos

Si utiliza ASN.1 con Unaligned PER, y definir los tipos de datos utilizando las restricciones apropiadas (por ejemplo, especificando más bajos límites superior / de números enteros, los límites superiores de la longitud de las listas, etc.), sus codificaciones serán muy compacto. No habrá bits de desperdicio para cosas como la alineación o relleno entre los campos, y cada campo se codificará 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 codifica en 3 bits (1 = '000', 2 = '001', ..., 8 = '111'); y una selección con cuatro alternativas ocupará 2 bits (que indican la alternativa elegida), además de los bits ocupados por la alternativa elegida. ASN.1 tiene muchas otras características interesantes que se han utilizado con éxito en muchas normas publicadas. Un ejemplo es el marcador de extensión ( "..."), que cuando se aplica a la secuencia, la elección, ENUMERATED, y otros tipos, permite la compatibilidad backward y hacia adelante entre los puntos finales de ejecución diferentes versiones de la especificación.

Cuando el tamaño del mensaje lleno / codificado es importante también tener en cuenta el hecho de que protobuf no es capaz de empaquetar campos repeated que no son de un primitive numeric type, leer este para más información.

Este es un problema, por ejemplo, si tiene mensajes de ese tipo: (comentario define alcance real de los 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 lleno de aproximadamente 250 a 450 bytes con protobuf, dependiendo de qué valores en realidad contiene la matriz. Esto puede incluso aumentar a más de 1000 bytes en el caso de que utilice el rango de 32 bits completo o en caso de que utilice int32 en lugar de sint32 y tienen valores negativos.

El blob datos en bruto (suponiendo que z se puede definir como valor int16) solamente consumiría 320 bytes y por lo tanto la ASN.1 mensaje es siempre menor que 320 bytes ya que los valores max no son realmente de 32 bits pero 19bit (x, y) y 15bit (z).

El tamaño del mensaje protobuf puede ser optimizado con esta definición 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 resulta en tamaños de mensajes entre aproximadamente 100 byte (todos los valores son ceros), 300 byte (los valores en el rango max), y 500 byte (todos los valores son altos valores de 32 bits).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top