2009-02-27 10 views
24

¿Cuáles son las diferencias más notorias entre Buffer de Protocolo de Google 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?¿Cómo se compara el Buffer de Protocolo de Google con ASN.1

+0

Quizás una pregunta relacionada: ¿por qué necesitamos los búferes de protocolo cuando ya tenemos un ASN.1 maduro? ¿El síndrome no inventado aquí en Google? –

Respuesta

8

Hace mucho tiempo que trabajo en ASN.1, pero es probable que el tamaño dependa de los detalles de sus tipos y datos reales.

Deseo fuertemente recomiendo que haga un prototipo de ambos y ponga algunos datos reales para comparar.

Si su búfer de protocolo contiene tipos primitivos repetidos, debe buscar en la fuente más reciente en Subversion para búferes de protocolo: ahora se pueden representar en un formato "empaquetado" que es mucho más eficiente en el uso del espacio. (Mi C# puerto tiene solo se encontró con esta característica, alguna vez la semana pasada.)

18

Si utiliza ASN.1 con el PER no alineado, y definir los tipos de datos que utilizan las restricciones apropiadas (por ejemplo, especificando inferior/superior límites 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 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 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.

3

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 repeated campos que no son de un primitive numeric type, read this para más información.

Esto es un problema, p. si tiene mensajes de ese tipo: (comentario define gama 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 lleno 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 use int32 en lugar de sint32 y tenga valores negativos.

El blob datos en bruto (suponiendo que z se puede definir como int16 valor) que sólo consumen 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 19 bits (x, y) y 15 bits (z).

El tamaño del mensaje protobuf se puede optimizar 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; 
} 

que resulta en mensaje de tamaños entre aproximadamente 100 byte (todos los valores son ceros), 300 byte (los valores en el rango max), y 500 byte (todos los valores son valores altos de 32 bits).

Cuestiones relacionadas