Serializando e desserializando o .NET Core vs Go Data

Olá% username%


Minha tarefa foi comparar o desempenho de serialização do .NET Core e Golang. Depois de pesquisar na Internet, deparei-me com um repositório . Um exemplo simples de um microsserviço REST é considerado. É exatamente disso que eu preciso, pensei. Depois de ver os resultados do teste, fiquei surpreso. Depois de olhar o código fonte, percebi o que estava errado. Aqui está o que eu não gostei:


  • Para serialização e desserialização, uma matriz de 3 elementos é selecionada. Isso claramente não é suficiente.
  • Para Golang, todos os recursos do idioma não são usados, mas, como você sabe, a biblioteca interna de codificação / json é lenta.
  • Como resultado, o autor compara o desempenho dos servidores web kestrel e net / http.

Foram essas deficiências que levaram a uma consideração mais detalhada do desempenho na estrutura do exemplo descrito acima. Espero que você ache interessante conhecer os resultados.


Composição e descrição do software


O código fonte do repositório acima também foi tomado como base. O que foi finalizado:


  • Para a API do servidor, fasthttp é usado.
  • O servidor da API responde com matrizes de registros.
  • Cada cliente possui vários métodos para verificação.

O código modificado está disponível no repositório .


Para maior clareza, um exemplo de resposta JSON da API do servidor:


[ { "Id":"id_8299119732867115081", "Name":"name_5541535679032008745", "Time":1566731141 }, ... { "Id":"id_2804604318195309547", "Name":"name_5914011395631118540", "Time":1566731142 } ] 

Clientes


Para avaliar o desempenho em cada serviço, três métodos são implementados:


  • recebendo dados da API do servidor e enviando-os sem processar [/ testNoProcess].
  • recebendo dados da API do servidor - desserialização, serialização usando reflexão e enviando [/ testReflection]. Para o .NETCore, foi utilizado o pacote Newtonsoft.Json, para Golang, a codificação / json.
  • recebendo dados da API do servidor - desserialização, serialização sem usar reflexão e enviando [/ testNoReflection]. Para o .NETCore, uma solução baseada em Span foi implementada para minimizar o número de alocações de memória. Golang tem uma solução pronta - a biblioteca easyjson , que se provou exclusivamente do lado positivo.

Com base nesses testes, é possível avaliar o desempenho relativo dos servidores Web (kestrel e net / http), o desempenho diminui ao processar dados usando reflexão e sem eles para implementações nos dois idiomas.


Descrição da metodologia de teste


Os testes foram realizados em várias etapas para avaliar o desempenho de cada idioma e cada implementação.
Para criar uma carga, o utilitário bombardier foi selecionado. O utilitário foi iniciado com os seguintes parâmetros: -c 125 –d 120s, que podem ser interpretados da seguinte maneira: como usar 125 threads com um tempo de teste de 120 segundos.


A medição do desempenho foi realizada em três etapas:


  1. Dimensão do servidor da API RPS. As medições foram realizadas para poder avaliar a influência dos métodos de processamento no desempenho de cada método.
  2. Medição RPS do processamento de resposta usando reflexão.
  3. Meça o processamento da resposta RPS sem usar reflexão.

Com base nessas medições, foram obtidos dados sobre o desempenho do processamento da resposta. A utilização de todos os núcleos do processador foi de 99,8 a 100%. Para a avaliação, foram selecionados os dados iniciais de 10, 30, 100 e 500 registros. Matrizes de 500 registros em produção não são comuns, mas eu estava interessado em ver como cada um dos idiomas se comporta.


Suporte de teste


Todos os testes foram executados em uma máquina virtual executando o Ubuntu Server 18.04 com todas as atualizações para agosto de 2019. Possui as seguintes características:


  • Núcleo do processador I7-3770K - 4 núcleos.
  • RAM - 4 GB.

Para comparação de desempenho, o .NET Core 2.2 e o Golang 1.12 foram instalados.


Bem, agora é hora de passar para o mais interessante - os resultados.


Resultados


Abaixo está uma tabela com os resultados do teste.


alt text


Você pode perceber imediatamente que Golang tem um servidor da web mais produtivo. A diferença é de cerca de 12% em comparação com o Kestrel no .NET Core.
Com base nos dados acima, foram construídos 2 gráficos. Em seguida, você pode ver claramente a comparação do RPS.


alt text


Devido à biblioteca de rede / http mais rápida, Golang mostra bons resultados para dados pequenos. Com um aumento no volume de dados, o desempenho é comparado ao kestrel.


Ao usar a reflexão em um tamanho pequeno de dados, o RPS é aproximadamente o mesmo, levando em consideração o erro de medição. Com o aumento do tamanho dos dados, o .NET Core mostra mais RPS.


Ao testar sem o uso de reflexão, os dois idiomas mostraram um ganho de desempenho. Golang mostra melhor desempenho porque inicialmente possui RPS (solicitações por segundo) mais altas em testes sem processamento. Em dados pequenos, a vantagem é significativa. Com o aumento do tamanho dos dados, o RPS é quase comparado. No maior teste de 500 registros, Golang está novamente à frente.


alt text


Em testes usando reflexão, Golang perdeu em todas as frentes. A queda de desempenho nos piores cenários foi superior a 60%. Implementar serialização pronta para o desempenho geralmente não vale nada.
Sem reflexão, Golang foi mais rápido em todos os testes. E com o crescimento dos dados, a vantagem da Golang está crescendo apenas. De qualquer forma, a recusa em usar a reflexão oferece um aumento significativo no desempenho para Golang e .NETCore, o que, em geral, deve ser esperado.


Conclusões


Que conclusões podem ser tiradas dessa pequena comparação de desempenho? Gostaria de formular isso na forma de prós e contras de cada uma das soluções. Vamos começar com Golang:


  • Ele tem melhor desempenho e pode ser aprimorado ainda mais, por exemplo, usando o fasthttp como servidor da web.
  • Graças à geração de código - uso conveniente de métodos de processamento sem usar reflexão.
  • Menos consumo de memória.

O .NET Core também possui várias vantagens:


  • O desempenho é adequado para a maioria dos casos.
  • Na minha opinião, este é um dos melhores e mais convenientes ambientes de desenvolvimento para o Visual Studio.

O resultado pode ser resumido da seguinte forma: se você possui uma API REST e planeja uma carga grande, lógica de negócios não muito complicada, é melhor usar o Golang; em outros casos, você pode fazer com o .NET Core. Devo reescrever soluções prontas do .NET Core para Golang? Todo mundo vai decidir por si mesmo.


Espero que você ache este material útil. Tudo de bom

Source: https://habr.com/ru/post/pt469271/


All Articles