11 pontos por dalinaum 2023-03-03 | 4 comentários | Compartilhar no WhatsApp

A equipe de recomendações da Kakao está desenvolvendo uma nova plataforma para substituir a plataforma de machine learning existente.

Havia certa dificuldade em garantir ao mesmo tempo desempenho e segurança da aplicação usando Python, a principal linguagem da equipe.

Ao introduzir Rust em uma aplicação de métricas de usuários, foi conduzido um processo de validação para verificar se implementar a aplicação em Rust seria apropriado.

  • Rust processou as tarefas cerca de 1,9 vez mais rápido que Python
  • No uso de memória, Python consumiu cerca de 4,5 vezes mais que Rust
  • O uso de CPU do Python foi até 3 vezes maior que o do Rust, com média de cerca de 2 vezes
  • Com asyncio no Python e tokio no Rust aplicados às aplicações de cada linguagem, mesmo em um ambiente single-thread em que o processamento assíncrono foi implementado da mesma forma, a velocidade de processamento de mensagens do Rust foi cerca de 10 vezes maior que a do Python.

Uma das grandes desvantagens do Rust foi o alto custo de aprendizado.

Mesmo ao desenvolver em Python, a equipe exigia type annotations. Ao implementar a aplicação de métricas de usuários em duas versões, não houve grande percepção de diferença no tempo de desenvolvimento entre Python e Rust.

Em termos de produtividade, a maior diferença percebida foi o tempo de compilação. (incluindo o tempo de download de pacotes no Docker)

  • Rust ficou em aproximadamente 340 segundos
  • No caso do Python, aproximadamente 100 segundos

No Python, dados criados em bibliotecas sem informações de tipo passam a ter o tipo Any, no qual a verificação de tipos é ignorada. Isso reduz a precisão da verificação de tipos em todo o projeto.

Também houve diferenças como o uso de exceções em Python e de um tipo enum chamado Result em Rust.

Ferramentas de desenvolvimento
No caso do Rust, o cargo oferece muitos recursos por padrão.
As ferramentas de desenvolvimento para Python estavam mais maduras e, com apenas a instalação, eram relativamente fáceis de usar.

4 comentários

 
jongpak 2023-03-03

Não tenho experiência nem com Python nem com Rust, mas, olhando só para o texto... não consegui perceber grandes vantagens na adoção de Rust.

Não que Rust seja ruim, mas os experimentos feitos para justificar sua adoção também parecem fracos
(sustentar que é várias vezes melhor só porque ficou várias vezes mais rápido com o resultado do processamento de apenas 50 mensagens me parece uma argumentação muito frágil..)

Além disso, nem foi uma comparação com a mesma lógica de processamento (síncrono vs assíncrono)..
[uma biblioteca Python que suporta processamento assíncrono de mensagens, mas sem muitas referências] vs [a linguagem Rust, que tem alto custo de aprendizado e risco de manutenção por depender de poucas pessoas]
Olhando para esses dois cenários, também fico em dúvida se houve uma reflexão séria sobre sustentabilidade no longo prazo (pelo menos foi essa a impressão que o texto me passou)

Pelas características de ETL, imagino que haja muitos casos em que seja preciso testar com frequência e em ciclos curtos, então build time de 100 segundos vs 300 segundos parece um grande gargalo no desenvolvimento..
O texto menciona que o build incremental é excelente, mas substitui essa parte por um hyperlink...

Na prática, provavelmente investigaram e avaliaram bastante. Mas, pelo menos pela sensação que o texto passa... fica difícil entender exatamente o que realmente melhorou com a adoção de Rust, quais eram os ganhos esperados e que problema isso resolveu, além de ser difícil se identificar com a argumentação..


Pessoalmente, já vi vários casos em que a tecnologia foi escolhida por ser a "tecnologia quente do momento" ou para colocar uma linha a mais no currículo, mas no fim a equipe não conseguia nem manter aquilo, e a maior parte das vezes isso acabou virando dívida técnica.

  • Por exemplo, quando insistem que precisa usar Kafka ou processamento assíncrono mesmo com uma carga de trabalho pequena, em que processamento sequencial não seria problema nenhum
  • Ou quando, sem considerar a realidade da equipe, aplicam algo porque disseram que assíncrono tem várias vantagens, e o resultado é que troubleshooting fica muito mais difícil e, no fim, isso vira mais um legado....
  • Ou quando dizem que adotar o tal ooo, que está em alta no momento, trará várias vantagens... mas aí logo aparece outro ooo ainda mais em alta, e passam a defender esse novo também..

Claro, não estou dizendo que esse texto sobre Rust seja assim, e espero que não seja..
Mas, depois de ver várias vezes que quem sofre com tecnologias adotadas sem reflexão séria são os membros da equipe, acho que acabei ficando mais cauteloso ao ler esse tipo de texto de promoção de tecnologia.

 
ehlegeth 2023-03-03

Basicamente parece uma task de ETL; vocês não consideraram Java, que também tem pontos fortes nesse domínio junto com Python? Se houve algum motivo para descartá-lo em favor do Rust, gostaria de saber.

 
kayws426 2023-03-03

Fica a sensação de que faltou algo, já que parte dos dados de comparação de desempenho foi obtida por meio de testes em pequena escala.

 
ehlegeth 2023-03-03

O significado dos testes de desempenho varia muito conforme a natureza da carga de trabalho, então é uma pena que não haja explicações sobre o desenho do teste ou sobre como os números foram obtidos.
Por exemplo, fiquei curioso para saber se, após processar 5 milhões de registros, foi usada uma média aritmética com base no processamento de 50 registros; se foi isso, como o uso de memória foi calculado; e como a diferença no uso de CPU foi medida. (O tempo provavelmente é wall-clock time, certo?)
Além disso, há a interpretação de que, “ao observar o uso de CPU, a maior parte da diferença de desempenho entre as duas linguagens veio do trabalho de consumo de mensagens do Kafka e de gravação de documentos no MongoDB, que são tarefas de entrada e saída (Input Output, doravante IO)”. Porém, nos resultados, foi dito que o wall-clock time do Rust foi cerca de metade, e o uso de CPU (CPU time?) foi 1/4,5. Então fico em dúvida se isso quer dizer uma diferença na forma de implementação relacionada a I/O, ou se se refere à diferença no processo de lidar com dados de I/O que exigem muito da CPU; há um ponto da lógica que não entendi muito bem. Na verdade, já é bem conhecido que o Rust tem vantagem em tarefas CPU-intensive, então, se for o segundo caso, nem parece haver muita necessidade de mencionar a diferença entre bibliotecas. Pelo contrário, se o experimento tratava de uma tarefa CPU-intensive, eu esperaria uma diferença bem maior, como na comparação entre implementações asyncio/tokio mencionada no texto; não seria mais correto interpretar que a diferença de desempenho acabou sendo menor por causa do I/O?