Skip to content

GSuaki/data-serialization-formats

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Serialização de dados e seus formatos

Introdução

Uma aplicação em execução mantém os dados em memória em formato de objetos, listas, arrays, hash tables, árvores, etc. Essas estruturas são utilizadas pois permitem que a CPU às acessem de maneira eficiente.

Como fazer quando queremos enviar esses dados em memória para outro local via rede?

Para trafegar esses dados via rede é necessário algum processo que agrupe as estruturas de dados em uma sequência de bytes.

Afinal de contas, não faz sentido enviar um ponteiro de memória para outra máquina 😅

  1. Esse processo de transformar as estruturas de dados em bytes é conhecido como ”serialização” (também pode ser chamado de encoding ou marshalling).

  2. O processo inverso, de transformar bytes em estrutura de dados, é conhecido como ”desserialização” (também pode ser chamado de decoding ou unmarshalling).

Para que você possa compreender mais facilmente os formatos de dados, é necessário saber dois conceitos: O Sistema Hexadecimal e a Tabela ASCII.

O Sistema Hexadecimal

Trata-se de um sistema de numeração posicional que representa os números em base 16, sendo assim, utilizando 16 símbolos. Este sistema utiliza os símbolos 0, 1, 2, 3, 4, 5, 6, 7, 8 e 9 do sistema decimal, além das letras A, B, C, D, E e F.

Cada número hexa significa quatro bits de dados binários. Um byte é criado por 8 bits e é representado por dois dígitos hexa.

Para saber mais...

A Tabela ASCII

Código Padrão Americano para o Intercâmbio de Informação (do inglês American Standard Code for Information Interchange - ASCII) é um sistema de representação de letras, algarismos e sinais de pontuação e de controle, através de um sinal codificado em forma de código binário (cadeias de bits formada por vários 0 e 1).

Em poucas palavras, essa tabela é usada para representar textos em computadores, equipamentos de comunicação, entre outros dispositivos que trabalham com texto.

Com a tabela é possível identificar que a letra A é equivalente ao byte 0100 0001. Como já aprendemos o Sistema Hexadecimal, toda vez que falarmos em binário, vamos utilizar sua representação em Hexadecimal para ficar mais enxuto (apenas dois caracteres). A letra A então fica 0x41 em Hexadecimal (mais legível que 0100 0001).

Para facilitar mais ainda a leitura, vamos cortar o começo 0x e só nos preocupar com os dois últimos dígitos: 41. Logo, podemos dizer que A é 41 em Hexadecimal.

Para reforçar o exercício, vá ate a tabela ASCII e tente encontrar a representação da letra M em Hexadecimal.

Se você encontrou 4d ou 4D, parabéns, você acertou!

Para saber mais...

Serializando os dados

Já aprendemos sobre os processos de serialização e desserialização. Agora precisamos saber qual formato escolher na hora de converter as estruturas de dados para binário.

Dentre os principais formatos, destaco dois: Formatos Textuais e Formatos Binários.

Para entender a diferença de um formato para o outro, vamos considerar a seguinte instância da classe Artist:

final Artist artist = 
    new Artist("Daft Punk", 1000, List.of("Orlando", "Nova York"));

A classe Artist possui três propriedades:

  • artistName que é uma String;
  • cache que é um Integer;
  • cities que é uma Lista de String.

Os Formatos Textuais

Para entender os formatos textuais, vamos analisar o resultado da serialização do objeto artist criado na sessão anterior.

Serializando em JSON, obtemos o seguinte resultado:

{
  "artist_name": "Daft Punk",
  "cache": 1000,
  "cities": [ "Orlando", "Nova York" ]
}

Como já sabemos que cada carácter pesa 1 byte e esse texto tem 71 caracteres ao todo, seu resultado final é de 73 bytes pois conta dois bytes adicionais são da notação JSON.

O mesmo objeto, mas agora em XML, obtemos o seguinte resultado:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <artistName>Daft Punk</artistName>
  <cache>1000</cache>
  <cities>
    <element>Orlando</element>
    <element>Nova York</element>
  </cities>
</root>

Reparem que a especificação do XML trabalha com tags (<element></element>), essa característica faz com que o resultado tenha uma quantia bem maior de caractéres e reflete diretamente no tamanho do resultado final que ficou em 173 bytes.

  • O XML contém os demarcadores <, / e >repetidas vezes para cada propriedade, além de tags de abertura e encerramento de propriedade. Essas características fazem com que seu tamanho seja superior ao do JSON.

  • O JSON por sua vez, demarcadores como " e :, mas repare que já em uma quantidade bem inferior a do XML. Por isso seu tamanho é 60% menor que o XML.

Os Formatos Binários

Para entender os formatos binários, também vamos analisar o resultado da serialização do objeto artist no começo da sessão "Serializando os dados".

Formato MessagePack

Serializando o objeto artist utilizando o formato MessagePack, vemos uma redução significante no tamanho do resultado final, que não tem uma representação textual legível.

Para ilustrar melhor, coloquei abaixo o binário do MessagePack em formato hexadecimal:

83 | ab | 61 72 74 69 73 74 5f 6e 61 6d 65 | a9 | 44 61 66 74 20 50 75 6e 6b |
   | a5 | 63 61 63 68 65 | cd | 03 e8 |
   | a6 | 63 69 74 69 65 73
92 | a7 | 4f 72 6c 61 6e 64 6f
   | a9 | 4e 6f 76 61 20 59 6f 72 6b

O resultado final cai de 73 bytes (em JSON) para 58 bytes em formato MessagePack, uma redução de ~25,5%. Isso se dá por conta de que é um formato um pouco mais enxuto, não conta com nenhum demarcador como : e ".

Traduzindo esse binário utilizando a tabela ASCII, fica mais fácil de entender o que está contido na mensagem:

Tradução do binário do MessagePack

Formato Avro

Serializando o objeto artist utilizando o formato Avro, vemos uma redução ainda mais significante no tamanho do resultado final, que não conta nem com qual propriedade do objeto aquele valor pertence. É literalmente uma concatenação de valores.

Para ilustrar melhor, coloquei abaixo o binário em formato hexadecimal:

12 | 44 61 66 74 20 50 75 6E 6B |
D0 | 0F |
04 |
0E | 4F 72 6C 61 6E 64 6F
12 | 4E 6F 76 61 20 59 6F 72 6B
00

O resultado cai de 73 bytes (em JSON) para 32 bytes em formato Avro, uma redução de ~56%.

Traduzindo esse binário utilizando a tabela ASCII, fica mais fácil de entender o que está contido na mensagem:

Tradução do binário do Avro

Referências

Especificação do JSON

Site do MessagePack

Especificação do MessagePack

Convertendo Object para binário com MessagePack

Site do Avro

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages