Pergunta

Quais são as maiores diferenças perceptíveis entre o Google Protocol Buffers e ASN.1 (com PER-encoding)? Para o meu projeto a questão mais imporant é o tamanho dos dados serializados. Alguém já fez quaisquer comparações de dados de tamanho entre os dois?

Foi útil?

Solução

É um longo tempo desde que eu tenha feito qualquer trabalho ASN.1, mas o tamanho é muito provável que dependem dos detalhes de seus tipos e dados reais.

Eu faria fortemente recomendamos que você protótipo tanto e colocar alguns dados reais para comparar.

Se o seu buffer de protocolo que contêm repetido tipos primitivos, você deve olhar para a mais recente fonte no Subversion para Protocol Buffers - eles podem ser representados em um formato de "embalado" agora que é muito mais eficiente de espaço. (Meu C # porta tem apenas apanhados com esse recurso, algum tempo na semana passada.)

Outras dicas

Se você usar ASN.1 com Unaligned PER, e definir seus tipos de dados usando as restrições adequadas (por exemplo, especificando / limites superiores mais baixos para números inteiros, limites superiores para o comprimento de listas, etc.), suas codificações será muito compactar. Não haverá pedaços desperdiçados para coisas como o alinhamento ou estofamento entre os campos, e cada campo será codificada no número mínimo de bits necessários para manter a sua faixa permitida de valores. Por exemplo, um campo do tipo INTEGER (1..8) serão codificados em 3 bits (1 '= 000', 2 = '001', ..., 8 = '111'); e uma escolha com quatro alternativas ocupará 2 bits (indicando a alternativa escolhida), mais os bits ocupada pelo alternativa escolhida. ASN.1 tem muitas outras características interessantes que têm sido utilizados com sucesso em muitas normas publicadas. Um exemplo é o marcador de extensão ( "..."), que, quando aplicado seqüência, escolha, enumerado, e outros tipos, permite a compatibilidade backward- e para a frente entre os terminais de aplicação diferentes versões da especificação.

Quando o tamanho do embalado mensagem / codificado é importante que você também deve observar o fato de que protobuf não é capaz de embalar campos repeated que não são de um primitive numeric type, ler este para obter mais informações.

Este é um problema, por exemplo, se você tem mensagens desse tipo: (comentário define intervalo 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;
}

No caso de você ter um comprimento de matriz de, por exemplo, 32 do que você poderia resultar em um tamanho da mensagem embalado de aproximadamente 250 a 450 bytes com protobuf, dependendo do que valoriza a matriz realmente contém. Isso pode até aumentar para mais de 1000 bytes no caso de você usar o intervalo de 32 bits completo ou no caso de você usar int32 vez de sint32 e têm valores negativos.

O blob de dados em bruto (assumindo que Z pode ser definido como valor int16) só iria consumir 320 bytes e assim a ASN.1 mensagem é sempre menor do que 320 bytes uma vez que os valores máximo são na verdade não 32bit mas 19bit (x, y) e 15bit (Z).

O tamanho da mensagem protobuf pode ser otimizado com esta definição mensagem:

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

o que resulta em tamanhos de mensagens entre aproximadamente 100 bytes (todos os valores são zero), 300 bytes (valores na escala máxima), e 500 bytes (todos os valores são valores elevados de 32 bits).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top