[NextStack] Por que Golang?

Uma série de artigos sobre a iniciativa NextStack, que pretende gerar conhecimento de tecnologias de forma empírica

Pedro Correa
Accenture Digital Product Dev
6 min readMar 17, 2022

--

Photo by Bruno Nascimento on Unsplash

Começamos hoe uma série de posts para ilustrar e defender uma iniciativa chamada de NextStack, que tem por objetivo gerar conhecimento de forma empírica. Como esses posts são preliminares, também vamos usar outras referências na literatura para validar nossos preconceitos.

Haiaku

Haiaku é o nome do pet project que vamos criar para adquirir capacidade técnicas nas tecnologias escolhidas. O projeto é uma aplicação web/mobile que consome uma API com ferramentas para desenvolvimento ágil.

A intenção desse é criar cenários reais de desenvolvimento de software para que consigamos gerar conhecimento das tecnologias de forma empírica. Esse conjunto de tecnologias que vamos utilizar estamos chamando de NextStack.

NextStack

Para desenvolver o Haiaku precisamos de uma stack sólida de tecnologias para criar tanto o back-end quando front-end. No back-end precisamos criar uma API para dar suporte ao aplicativo web/mobile, e, para isso, precisamos, por sua vez, de uma linguagem de programação robusta.

O termo robusto é muito vago e por isso criamos a seguinte lista de itens que precisamos avaliar:

  • [ ] Comunidade
  • [ ] Aprendizado Rápido
  • [ ] Desenvolvimento Rápido
  • [ ] Escalável
  • [ ] Baixo uso de RAM
  • [ ] Tempo de Processamento
  • [ ] Ferramentas

A seguir, vamos discutir cada um desses itens:

Suporte e Comunidade

De nada adianta escolhermos uma linguagem com uma comunidade morta. Sem uma comunidade, a resolução de problemas se torna mais difícil e a evolução do ecossistema e manutenção da linguagem é lenta ou inexistente.

Na lista abaixo temos as linguagens mais populares do StackOverflow em 2021. Vamos usá-la como ponto de partida para selecionar linguagens populares, que é um bom indicativo de uma comunidade ativa.

Se fizermos uma limpeza das linguagens que não servem para criar backends (html, CSS, etc) e agruparmos algumas linguagens temos a seguinte lista:

  • JS/Node/Typescript
  • Python
  • Java
  • C#/C++/C
  • Go
  • Rust

Javascript pode ser considerado parte do “Current Stack” dos projetos que mais tenho visto sair aqui nos times de produtos digitais da Accenture. Ela é uma linguagem fácil de aprender, popular e funciona tanto para back quanto front-end.

Apesar disso, Javascript não é uma linguagem bala de prata e possui seus problemas, como grande consumo de memória e baixa performace comparada a outras linguagens mais “modernas”.

Outro problema é a tendência natural dos projetos Javascript ficarem “caóticos”. Apesar do JS ter amadurecido para projetos grandes, principalmente com a criação do Typescript, no fim do dia o Typescript nada mais é que arquivo JS e ele vai sofrer dos mesmos problemas fundamentais.

Por ser considerado parte do “Current Stack”, vamos usar JS como referência para as comparações a seguir.

Uso de recursos e Performance

Nesse projeto queremos utilizar uma arquitetura Serverless afim de simplificar nossa infraestrutura cloud ao mesmo tempo em que reduzimos custo e delegamos (boa parte) a responsabilidade de disponibilidade para o cloud provider.

Uma arquitetura Serverless se beneficia grandemente de execuções rápidas e pouco uso de memória RAM, que influenciam diretamente no custo da aplicação. Por isso precisamos de uma linguagem rápida, leve e performática. Dito isso, mesmo que não fôssemos usar Serverless a escolha da linguagem se mantém válida pelos mesmos motivos.

Para comparar esses valores usamos o site Benchmark Game que compara múltiplos algoritmos rodando em múltiplas linguagens dizendo dentre outras coisas o tempo de execução e de memória. Não consideramos isso uma forma ideal de comparação de linguagens mas é um excelente ponto de partida.

Pelos dados do site conseguimos eliminar algumas linguagens que ficam consideravelmente atrás de um segundo grupo mais performático. Com isso temos a seguinte lista filtrada:

  • C#/C++/C
  • Go
  • Rust

A eliminação de certa forma é meio óbvia: removemos JavaScript, Python e Java. Linguagens compiladas (quase) sempre são mais performáticas que linguagens interpretadas. Java em especial é infamemente conhecida por comer mais RAM do que o Chrome e conseguimos ver isso nas execuções do Benchmark Game.

Algumas comparações que merecem destaque são Go vs JavaScript, na qual podemos ver que em alguns casos Go mostra até 30x menos uso de RAM e até 2x menos tempo de execução em alguns casos. O resultado comparado a Python e Java se mantém na mesma magnitude.

Comparando Go com Rust vemos que Rust tem ainda menos uso de RAM com execução até 3x mais rápida. Esse pulo incremental de performance vem com o custo de uma linguagem mais complexa e com maior curva de aprendizado. Por sua vez, Rust comparado com C se mantém próximo da família C.

Aprendizado e Desenvolvimento Rápidos

A família de linguagens C são globalmente consideradas difíceis de aprender e mais ainda de ter maestria. Por isso, vamos removê-la logo de cara e, assim, restam apenas Rust e Go.

Confesso que gostaria de uma oportunidade para aprender mais Rust, porém, como consultoria, precisamos entender o cenário econômico-social em que as linguagens se encontram.

Em resumo: faltam profissionais de TI, logo precisamos de uma linguagem de fácil acesso que permita que novos desenvolvedores aprendam de forma rápida. Além disso, time-to-market é uma variável cada vez mais crítica, então precisamos de uma linguagem que permita desenvolvimento rápido.

Considerando as duas linguagens restantes, Go ganha no quesito de velocidade de aprendizado e desenvolvimento. Na verdade esse é um ponto de grande divergência entre as linguagens. Go preza pela simplicidade e quase minimalismo, enquanto que Rust possui uma quantidade de ferramentas que muitos desenvolvedores se sentem até overwhelmed.

Escabilidade

Por se tratar de uma linguagem que será usada para criar uma API precisamos que ela seja capaz de escalar, ou seja, de atender uma crescente quantidade de pedidos em um tempo determinado.

Neste link temos um comparativo entre Elixir, Go e Nodejs na visão de escalabilidade e quantidade de chamadas de API e Rede. Nele, vemos que Elixir e Go se comportam de forma muito parecida, mas Nodejs fica a desejar em alguns pontos, como o tempo de latência.

Uma das comparações mais interessantes para este tópico é o gráfico abaixo:

Nele podemos ver que Go e Elixir se mantêm extremamente próximos ao tempo de resposta de 100ms de timeout imposto na aplicação. Isso é mais que 75% menor que a do Nodejs. Também é importante vermos que não só a média é menor como também se mantém super estável ao longo da execução, ou seja, o tempo de resposta do Go é mais consistente, o que indica que o processo roda com mais “folga” que o do Nodejs.

Ferramentas

Um último ponto vital é o ecossistema e ferramentas disponíveis para as linguagens. Comparado com JavaScript, o Go e o Rust possuem bem menos ferramentas disponíveis, porém as que existem já garantem um ecossistema robusto.

Dentre elas temos ferramentas nativas de gestão de pacotes, formatação de código e bibliotecas nativas para uma vasta quantidade de problemas.

Conclusões iniciais

Não foi nossa intenção comparar à exaustão as linguagens disponíveis para o projeto. Neste post apenas tentamos levantar os pontos que consideramos mais importantes para nosso cenário, que apesar de específico engloba boa parte das soluções que trabalhamos. Se quiser saber mais detalhes, recomendo os links de referência no final do post.

No final, Go atende todos os nossos requisitos previamente listados e vamos é por isso que vamos usá-la para criação da API. Fiquem ligados que logo tem mais posts sobre nossa experiência prática no uso da linguagem para criação de APIs. Até lá!

--

--