Recentemente, encontrei o MessagePack , um formato alternativo de serialização binária para os Protocol Buffers e JSON do Google, que também superam os dois.
Também há o formato de serialização BSON usado pelo MongoDB para armazenar dados.
Alguém pode elaborar as diferenças e as desvantagens / vantagens do BSON vs MessagePack ?
Apenas para completar a lista de formatos de serialização binária de alto desempenho: Existem também Gobs que serão os sucessores dos Buffers de Protocolo do Google . No entanto, em contraste com todos os outros formatos mencionados, esses não são independentes de idioma e dependem da reflexão interna do Go. Existem também bibliotecas Gobs para pelo menos outro idioma que não o Go.
Respostas:
// Por favor, note que sou autor do MessagePack. Esta resposta pode ser tendenciosa.
Design de formato
Compatibilidade com JSON
Apesar do nome, a compatibilidade do BSON com o JSON não é tão boa em comparação com o MessagePack.
O BSON possui tipos especiais como "ObjectId", "Min key", "UUID" ou "MD5" (acho que esses tipos são exigidos pelo MongoDB). Esses tipos não são compatíveis com JSON. Isso significa que algumas informações de tipo podem ser perdidas quando você converte objetos de BSON para JSON, mas é claro apenas quando esses tipos especiais estão na fonte BSON. Pode ser uma desvantagem usar o JSON e o BSON no serviço único.
O MessagePack foi projetado para ser convertido de forma transparente de / para JSON.
O MessagePack é menor que o BSON
O formato do MessagePack é menos detalhado que o BSON. Como resultado, o MessagePack pode serializar objetos menores que o BSON.
Por exemplo, um mapa simples {"a": 1, "b": 2} é serializado em 7 bytes com o MessagePack, enquanto o BSON usa 19 bytes.
BSON suporta atualização no local
Com o BSON, você pode modificar parte do objeto armazenado sem serializar novamente todo o objeto. Vamos supor que um mapa {"a": 1, "b": 2} seja armazenado em um arquivo e você deseje atualizar o valor de "a" de 1 a 2000.
Com o MessagePack, 1 usa apenas 1 byte, mas 2000 usa 3 bytes. Portanto, "b" deve ser movido para trás em 2 bytes, enquanto "b" não é modificado.
Com o BSON, 1 e 2000 usam 5 bytes. Devido a essa verbosidade, você não precisa mover "b".
O MessagePack possui RPC
MessagePack, Buffers de Protocolo, Thrift e Avro suportam RPC. Mas o BSON não.
Essas diferenças implicam que o MessagePack foi originalmente projetado para comunicação em rede, enquanto o BSON foi projetado para armazenamento.
Implementação e design da API
O MessagePack possui APIs de verificação de tipo (Java, C ++ e D)
O MessagePack suporta digitação estática.
A digitação dinâmica usada com JSON ou BSON é útil para linguagens dinâmicas como Ruby, Python ou JavaScript. Mas problemático para linguagens estáticas. Você deve escrever códigos de verificação de tipo chatos.
O MessagePack fornece API de verificação de tipo. Ele converte objetos de tipo dinâmico em objetos de tipo estaticamente. Aqui está um exemplo simples (C ++):
O MessagePack tem IDL
Está relacionado à API de verificação de tipo, o MessagePack suporta IDL. (a especificação está disponível em: http://wiki.msgpack.org/display/MSGPACK/Design+of+IDL )
Os buffers de protocolo e o Thrift requerem IDL (não suportam digitação dinâmica) e fornecem uma implementação IDL mais madura.
O MessagePack possui API de streaming (Ruby, Python, Java, C ++, ...)
O MessagePack suporta desserializadores de streaming. Esse recurso é útil para comunicação em rede. Aqui está um exemplo (Ruby):
fonte
Eu sei que esta questão está um pouco datada neste momento ... Eu acho muito importante mencionar que depende da aparência do seu ambiente cliente / servidor.
Se você estiver passando bytes várias vezes sem inspeção, como um sistema de fila de mensagens ou entradas de log de streaming em disco, poderá preferir uma codificação binária para enfatizar o tamanho compacto. Caso contrário, é um problema caso a caso em diferentes ambientes.
Alguns ambientes podem ter serialização e desserialização muito rápidas de / para o msgpack / protobuf, outros nem tanto. Em geral, quanto mais baixo o nível do idioma / ambiente, melhor a serialização binária funcionará. Em idiomas de nível superior (node.js, .Net, JVM), você verá frequentemente que a serialização JSON é realmente mais rápida. A questão então é: a sobrecarga da sua rede é mais ou menos restrita que a sua memória / CPU?
No que diz respeito aos buffers msgpack vs bson vs protocol ... msgpack é o mínimo de bytes do grupo, sendo os buffers de protocolo os mesmos. O BSON define tipos nativos mais amplos que os outros dois e pode ser uma melhor correspondência para o modo de objeto, mas isso o torna mais detalhado. Os buffers de protocolo têm a vantagem de serem projetados para transmitir ... o que o torna um formato mais natural para um formato de transferência / armazenamento binário.
Pessoalmente, eu me inclinaria para a transparência que o JSON oferece diretamente, a menos que haja uma clara necessidade de tráfego mais leve. Sobre HTTP com dados compactados em gz, a diferença na sobrecarga da rede é ainda menos problemática entre os formatos.
fonte
O teste rápido mostra que o JSON minificado é desserializado mais rapidamente que o MessagePack binário. Nos testes, Article.json é JSON compactado em 550kb, Article.mpack é a versão MP em 420kb. Pode ser uma questão de implementação, é claro.
MessagePack:
JSON:
Então os tempos são:
Então o espaço é economizado, mas mais rápido? Não.
Versões testadas:
fonte
simplejson
2.6.2 leva 66.7 segundos e omsgpack
0.2.2 leva apenas 28.8.Uma diferença importante ainda não mencionada é que o BSON contém informações de tamanho em bytes para o documento inteiro e outros sub-documentos aninhados.
Isso tem dois grandes benefícios para ambientes restritos (por exemplo, incorporados), onde tamanho e desempenho são importantes.
fonte
Fiz benchmark rápido para comparar a velocidade de codificação e decodificação do MessagePack vs BSON. BSON é mais rápido, pelo menos, se você tiver grandes matrizes binárias:
Usando C # Newtonsoft.Json e MessagePack por neuecc:
fonte
Bem, como o autor disse, o MessagePack foi originalmente projetado para comunicação em rede, enquanto o BSON foi projetado para armazenamento.
O MessagePack é compacto enquanto o BSON é detalhado. O MessagePack deve economizar espaço, enquanto o BSON é projetado para CURD (economia de tempo).
Mais importante, o sistema de tipos do MessagePack (prefixo) segue a codificação Huffman, aqui eu desenhei uma árvore Huffman do MessagePack (clique no link para ver a imagem) :
fonte