Pergunta

Alguém com experiência com essas bibliotecas tiver qualquer comentário sobre qual deles preferiram? Houve alguma diferença de desempenho ou dificuldades em utilizar?

Foi útil?

Solução

Eu brinquei um pouco com ambos os sistemas, nada de grave, apenas algumas coisas hackish simples, mas eu senti que há uma verdadeira diferença na forma como você deveria usar as bibliotecas.

Com boost :: serialização, você escrever seus próprios structs / classes primeiro, e depois adicionar os métodos de arquivamento, mas você ainda deixou com algumas bonitas aulas "slim", que pode ser usado como membros de dados, herdada, qualquer que seja .

Com buffers de protocolo, a quantidade de código gerado para até mesmo uma estrutura simples é bastante substancial, e as estruturas e código que é gerado é mais significou para operar, e que utilize a funcionalidade buffers de protocolo com dados de transporte de e para o seu próprias estruturas internas.

Outras dicas

Estou usando o impulso de serialização por um longo tempo e apenas escavado em buffers de protocolo, e eu acho que eles não têm exatamente o mesmo propósito. BS (não ver que vem) economiza seu C ++ objetos a um córrego, ao passo que PB é um formato de intercâmbio que você leia para / de.

datamodel da PB é a maneira mais simples: você recebe todos os tipos de ints e flutuadores, cordas, matrizes, estrutura básica e isso é muito bonito isso. BS permite que você diretamente salvar todos os seus objetos em uma única etapa.

Isso significa que com BS lo a obter mais dados sobre o fio, mas você não tem que reconstruir toda a sua estrutura de objetos, enquanto buffers de protocolo é mais compacto, mas há mais trabalho a ser feito após a leitura do arquivo. Como o nome diz, é para protocolos (linguagem-agnóstico, espaço de dados eficientes passando), o outro é para a serialização (acéfalo objetos poupança).

Então, o que é mais importante para você:? Velocidade eficiência / espaço ou código limpo

Há um par de preocupações adicionais com boost.serialization que eu vou adicionar à mistura. Ressalva:. Eu não tenho nenhuma experiência direta com buffers de protocolo para além roçando os docs

Nota que, enquanto eu acho impulso, e boost.serialization, é ótimo no que faz, eu vim à conclusão de que os formatos de arquivo padrão que vem com não são uma ótima opção para um formato de fio.

É importante distinguir entre as versões do sua classe (como mencionado em outras respostas, boost.serialization tem algum suporte para dados de versão) e compatibilidade entre as diferentes versões do Biblioteca de serialização .

Versões mais recentes do boost.serialization não pode gerar arquivos que versões mais antigas pode desserializar (o inverso não é verdadeiro: as versões mais recentes são sempre a intenção de arquivos desserializar feitas por versões mais antigas).. Isto levou aos seguintes problemas para nós:

  • Tanto o nosso software de cliente e servidor criar objetos que os outros consome, por isso só pode mover-se para uma boost.serialization mais recente se atualizar cliente e servidor em sincronia serializado. (Este é um grande desafio em um ambiente onde você não tem controle total de seus clientes).
  • impulso vem como uma grande biblioteca com peças compartilhadas, e tanto o código de serialização e as outras partes da biblioteca de impulso (por exemplo shared_ptr) pode estar em uso no mesmo arquivo, não posso atualizar qualquer partes de impulso, porque eu não posso atualizar boost.serialization. Eu não tenho certeza se é possível / / sane seguro para tentar ligar várias versões de impulso em um único executável, ou se temos o orçamento / energia para refatorar os bits que precisam permanecer em uma versão mais antiga do impulso em um separado executável (DLL no nosso caso).
  • A versão antiga do impulso que estamos no preso não suporta a última versão do compilador que usamos, por isso está preso em uma versão antiga do compilador também.

O Google parece realmente publicar o protocolo buffers fio formato , e Wikipedia descreve-os como frente-compatível, compatível com versões anteriores (embora eu acho que Wikipedia está se referindo a dados de versão do protocolo, em vez de tampão de versão de biblioteca). Embora nenhum destes é uma garantia de frente-compatibilidade, parece que uma indicação mais forte para mim.

Em resumo, Eu preferiria, um formato de fio publicada conhecido como buffers de protocolo quando eu não tenho a capacidade de atualizar o cliente e servidor em sincronia.

Nota de rodapé:. Plug descarado para um relacionada resposta por mim

serialização impulso

  • é uma biblioteca para escrever dados em um córrego.
  • não dados compressa.
  • não suporta dados de versão automaticamente.
  • recipientes suportes STL.
  • Propriedades de dados escritos dependem correntes escolhidas (por exemplo endian, comprimido).

Protocol Buffers

  • gera um código de descrição de interface (suporta C ++, Python e Java por padrão. C, C # e outros por parte 3).
  • opcionalmente comprime os dados.
  • alças de dados de versões automaticamente.
  • alças swapping endian entre plataformas.
  • não suporta contêineres STL.

Aumento de serialização é uma biblioteca para converter um objeto em um fluxo serializado de dados. Protocol Buffers fazer a mesma coisa, mas também fazer outros trabalhos para você (como versionamento e troca endian). Impulso serialização é mais simples para "pequenas tarefas simples". Protocol Buffers é provavelmente melhor para "maior infra-estrutura".

EDIT: 24-11-10:. Adicionado "automaticamente" a BS versões

Eu não tenho nenhuma experiência com impulso de serialização, mas tenho buffers protocolo utilizado. I como protocolo buffers muito. Mantenha em mente o seguinte (digo isto com nenhum conhecimento de aumento).

    buffers
  • Protocolo são muito eficientes para que eu não faça imaginar que ser um sério impulso questão vs..
  • buffers protocolo constituem uma representação intermediária que trabalha com outras línguas (Python e Java ... e mais nas obras). Se você sabe que você está usando apenas C ++, talvez impulso é melhor, mas a opção de usar outros idiomas é bom.
  • buffers de protocolo são mais como recipientes de dados ... não há natureza orientada a objetos, como herança. Pense sobre a estrutura do que você quer serialize.
  • buffers
  • Protocolo são flexíveis porque você pode adicionar campos "opcionais". Isto significa basicamente que você pode alterar a estrutura de buffer de protocolo sem quebrar a compatibilidade.

Espero que isso ajude.

boost.serialization só precisa o compilador C ++ e dá-lhe um pouco de açúcar sintaxe como

serialize_obj >> archive;
// ...
unserialize_obj << archive;

para salvar e carregar. Se C ++ é a única linguagem que você usa você deve dar boost.serialization um tiro sério.

Eu dei uma olhada rápida em buffers de protocolo do Google. Pelo que vejo eu diria que não é directamente comparável com boost.serialization. Você tem que adicionar um compilador para os arquivos .proto ao seu conjunto de ferramentas e manter os arquivos .proto si. A API não integrar em C ++ como boost.serialization faz.

boost.serialization faz o trabalho a sua projetado para muito bem: a objetos serialize C ++ :) OTOH uma consulta de API, como buffers de protocolo Google tem lhe dá mais flexibilidade.

Desde que eu utilizado apenas boost.serialization até agora eu não posso comentar sobre comparação de desempenho.

Correção acima (acho que isso é essa resposta ) sobre a serialização Boost:

Ele não permite apoiar dados de versão .

Se você precisar de compressão -. Usar um fluxo comprimido

Pode lidar com troca endian entre plataformas como a codificação pode ser um texto, binário ou XML.

Eu nunca implementado qualquer coisa usando a biblioteca de impulso, mas eu achei Google protobuff de ser mais pensada, eo código é muito mais limpo e mais fácil de ler. Gostaria de sugerir ter um olhar para os vários idiomas que deseja usá-lo com e ter uma leitura através do código e da documentação e fazer a sua mente.

A única dificuldade que tive com protobufs foi deram o nome de uma função muito comumente usado em seu código gerado GetMessage (), que de conflitos claro, com a macro Win32 GetMessage.

Eu gostaria ainda recomendo protobufs. Eles são muito úteis.

Tal como acontece com quase tudo em engenharia, a minha resposta é ... "depende".

Ambos são bem testados, tecnologias aprovados. Ambos vão levar os seus dados e transformá-lo em algo amigável para o envio de algum lugar. Ambos provavelmente será rápido o suficiente, e se você está contando realmente um byte aqui ou ali, você provavelmente não vai ser feliz com (vamos enfrentá-lo ambos os pacotes criados será uma pequena fração do XML ou JSON).

Para mim, ele realmente se resume a fluxo de trabalho e se ou não você precisa de algo diferente de C ++ na outra extremidade.

Se você quiser descobrir o seu conteúdo de mensagens em primeiro lugar e você está construindo um sistema a partir do zero, usar o protocolo buffers. Você pode pensar a mensagem de uma forma abstrata e, em seguida, gerar automaticamente o código em qualquer idioma que você quer (3ª plugins do partido estão disponíveis para quase tudo). Além disso, acho colaboração simplificada com Protocol Buffers. Eu só enviar mais de um arquivo .proto e, em seguida, a outra equipe tem uma idéia clara do que os dados estão sendo transferidos. Eu também não impor nada sobre eles. Se eles querem usar Java, vá em frente!

Se eu já construiu uma classe em C ++ (e isso aconteceu mais vezes do que não) e eu quero enviar que os dados sobre o fio agora, impulso serialização, obviamente, faz uma tonelada de sentido (especialmente onde eu já tenho um impulso dependência em outro lugar).

Você pode usar o aumento de serialização em conjunto apertado com seus objetos de domínio "reais", e serializar a hierarquia de objetos completo (herança). não Protobuf não suporta herança, assim você terá que agregação de uso. Pessoas argumentam que Protobuf deve ser usado para DTOs (objetos de transferência de dados), e não para o domínio do núcleo objetos em si. Eu tenho usado tanto boost :: serialização e protobuf. O desempenho de boost :: serialização deve ser levado em conta, cereal pode ser uma alternativa.

Eu sei que esta é uma questão mais velho agora, mas eu pensei que eu ia jogar meu 2 pence em!

Com impulso que você começa a oportunidade de que estou escrever alguma validação de dados em suas classes; isso é bom porque a definição de dados e os controlos da validade estão todos em um só lugar.

Com GPB o melhor que você pode fazer é colocar comentários no arquivo .proto e esperança contra toda a esperança que quem está usando ele lê-lo, presta atenção a ela, e implementa a validade próprios cheques.

É desnecessário dizer que isso é improvável e pouco confiável se o seu confiar em alguém na outra extremidade de um fluxo de rede para fazer isso com o mesmo vigor como a si mesmo. Além disso, se as restrições sobre a mudança validade, várias alterações de código precisa ser planejado, coordenado e feito.

Assim, considero GPB inadequado para desenvolvimentos onde há pouca oportunidade de regularmente encontrar e conversar com todos os membros da equipe.

== EDIT ==

O tipo de coisa que quero dizer é o seguinte:

message Foo
{
    int32 bearing = 1;
}

Agora, quem pode dizer o que o intervalo válido de bearing é? Podemos ter

message Foo
{
    int32 bearing = 1;  // Valid between 0 and 359
}

Mas isso depende de alguém lendo este e escrever código para ele. Por exemplo, se você editá-lo e a restrição torna-se:

message Foo
{
    int32 bearing = 1;  // Valid between -180 and +180
}

você está completamente dependente de todos que tem usado esse .proto atualizando seu código. Isso não é confiável e caro.

Pelo menos com a serialização impulso que você está distribuindo uma única classe C ++, e que pode ter verificações de validade de dados construídos para a direita nele. Se as mudanças restrições, então ninguém mais necessidade fazer qualquer trabalho que não certificando-se que eles estão usando a mesma versão do código-fonte como você.

Alternativa

Há uma alternativa: ASN.1. Esta é antiga, mas tem algumas coisas realmente, realmente, acessível:

Foo ::= SEQUENCE
{
   bearing INTEGER (0..359)
}

Observe a restrição. Assim, sempre que alguém consome esse arquivo .asn, gera código, eles acabam com o código que irá verificar automaticamente que bearing está em algum lugar entre 0 e 359. Se você atualizar o arquivo .asn,

Foo ::= SEQUENCE
{
   bearing INTEGER (-180..180)
}

tudo que eles precisam fazer é recompilação. Nenhuma outra alteração de código são necessários.

Você também pode fazer:

bearingMin INTEGER ::= 0
bearingMax INTEGER ::= 360

Foo ::= SEQUENCE
{
   bearing INTEGER (bearingMin..<bearingMax)
}

Observe o <. E também na maioria das ferramentas do bearingMin e bearingMax pode aparecer como constantes no código gerado. Isso é extremamente útil.

As restrições podem ser bastante elaborado:

Garr ::= INTEGER (0..10 | 25..32)

Olhe para Capítulo 13 neste PDF ; é incrível o que você pode fazer;

Arrays podem ser constrangidos demasiado:

Bar ::= SEQUENCE (SIZE(1..5)) OF Foo
Sna ::= SEQUENCE (SIZE(5)) OF Foo
Fee ::= SEQUENCE 
{
    boo SEQUENCE (SIZE(1..<6)) OF INTEGER (-180<..<180)
}

ASN.1 é antiquado, mas ainda ativamente desenvolvido, amplamente utilizado (seus usos de telefonia móvel que muito), e muito mais flexível do que a maioria das outras tecnologias de serialização. Sobre a única deficiência que eu posso ver é que não há gerador de código decente para Python. Se você estiver usando C / C ++, C #, Java, ADA, então você está bem servida por uma mistura de ferramentas livre (C / C ++, ADA) e comercial (, C #, JAVA C / C ++).

Eu gosto especialmente a grande variedade de wireformats baseados binários e texto. Isto torna extremamente conveniente em alguns projetos. A lista wireformat atualmente inclui:

  • BER (binário)
  • PER (binário, alinhadas e desalinhadas. Este é ultra pouco eficiente. Por exemplo, e INTEIRO constrangido entre 0 e 15 vai ocupar apenas 4 bits no fio)
  • OER
  • DER (outro binário)
  • XML (também XER)
  • JSON (nova marca, o apoio ferramenta ainda está em desenvolvimento)

além de outros.

Observe os dois últimos? Sim, você pode definir estruturas de dados em ASN.1, gerar o código, e emitem / consumir mensagens em XML e JSON. Nada mal para uma tecnologia que começou na década de 1980.

Versioning é feito de forma diferente para GPB. Você pode tudoow para extensões:

Foo ::= SEQUENCE
{
   bearing INTEGER (-180..180),
   ...
}

Isso significa que em uma data posterior que pode adicionar ao Foo, e sistemas mais antigos que têm esta versão pode ainda trabalho (mas só pode acessar o campo bearing).

I taxa ASN.1 muito. Pode ser uma dor de lidar com (ferramentas podem custar dinheiro, o código gerado não é necessariamente bonito, etc). Mas as restrições são uma característica verdadeiramente fantástico que me salvou toda uma tonelada de tempo coração doer e outra vez. Faz desenvolvedores whinge muito quando os codificadores / decodificadores relatam que eles têm gerado dados Duff.

Outros links:

Observações

Para compartilhar dados:

  • Código primeiras aproximações (por exemplo impulso serialização) restringi-lo a língua original (por exemplo, C ++), ou forçá-lo a fazer um monte de trabalho extra em outro idioma
  • Schema primeiro é melhor, mas
    • Muitos desses grandes lacunas licença no contrato de partilha (ou seja, sem restrições). GPB é irritante a esse respeito, porque é de outra maneira muito boa.
    • Alguns têm restrições (por exemplo, XSD, JSON), mas sofrem apoio ferramenta irregular.
    • Por exemplo, xsd.exe da Microsoft ignora ativamente restrições em arquivos XSD (desculpa de MS é realmente fraco). XSD é bom (dos constrangimentos ponto de vista), mas se você não pode confiar no outro cara para usar uma ferramenta boa XSD que as aplica para ele / ela, em seguida, o valor de XSD é diminuída
    • JSON validadores são ok, mas eles não fazem nada para ajudá-lo a formar o JSON, em primeiro lugar, e não são chamados automaticamente. Não há nenhuma garantia de que alguém lhe enviando mensagem JSON têm executá-lo através de um validador. Você tem que lembrar para validá-lo a si mesmo.
    • ferramentas ASN.1 todos parecem implementar as restrições de verificação.

Então, para mim, ASN.1 faz. É o que é menos provável que resulte em alguma outra pessoa a cometer um erro, porque é o único com as características certas e onde as ferramentas todas aparentemente esforços para aplicar plenamente essas características, e é linguagem bastante neutro para a maioria dos propósitos.

Para ser honesto, se GPB adicionado um mecanismo restrições que seria o vencedor. XSD é perto, mas as ferramentas são quase universalmente lixo. Se houvesse geradores de código decentes de outras línguas, esquema JSON seria muito bom.

Se GPB tinha restrições adicionado (nota: isto não mudaria qualquer um dos formatos de arame), que seria a única que eu recomendo a todos para quase todos os fins. Embora uper de ASN.1 é muito útil para as ligações de rádio.

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