Python combina com performance?

Carlos Eduardo Millani
Ambev Tech
Published in
4 min readMar 18, 2022

Por Carlos Eduardo Millani
Arquiteto de Software | Ambev Tech

Imagem: reprodução internet

Tome o seguinte cenário: devemos implementar um algoritmo que recebe uma lista de carrinhos de compra e retorna o ticket médio. Cada carrinho tem apenas um produto, com seu preço e quantidade. Representando em Python seria algo assim:

Uma solução simples seria iterar na lista de objetos, multiplicando o preço pela quantidade e dividindo pelo tamanho da lista:

Quão rápido é executar esse cálculo?

Executando em meu notebook pessoal com uma lista com 1 milhão de carrinhos essa função leva:

0.075 segundos

E se o mesmo fosse implementado em C#?

0.017 segundos!

Já ganhamos tempo, vamos descer mais um pouco o nível: e em C?

0.003 segundos!

Mas Python tem um truque na manga. Vamos deixar o trabalho pesado para uma biblioteca externa:

Utilizando a biblioteca Pandas (que debaixo dos panos utiliza C) conseguimos chegar em:

0.0045 segundos!

Os cálculos acima são exemplos rudimentares que podem variar entre máquinas, e não devem ser considerados um benchmark. O intuito dessa comparação é apenas ressaltar o quão fácil é escrever um código versus quão rápido ele é

Mas C puro ainda ganha!

Até aqui falamos de performance da execução do código, vamos pensar um pouco agora sobre a “performance” de desenvolvimento.

Quão complexo é escrever e manter um código que utiliza a API da biblioteca Pandas para os cálculos?

Nosso time quase todo veio de contextos bem diferentes do Python, como Java e C#, mas em alguns dias já conseguiam escrever código com as novas ferramentas. Além da própria facilidade da sintaxe do Python, o Pandas torna a intenção do cálculo mais clara.

E fazer as mesmas operações em C?

Aqui a performance do desenvolvedor sofre uma grande penalidade: a sintaxe é mais complexa, é necessário controlar manualmente a alocação de memória e é muito fácil cometer deslizes. No exemplo acima o código ainda fica simples, mas quando falamos de operações de joins em datasets distintos e agrupamentos a implementação já se torna infinitamente mais complexa.

Quando falamos sobre desenvolvimento de um novo produto devemos pensar não só na funcionalidade que será entregue, mas também na qualidade e velocidade do que está sendo desenvolvido e a “performance” de desenvolvimento é muito mais alta em uma linguagem de mais alto nível.

C# e outras linguagens, como Rust, também fornecem bibliotecas que lidam com DataFrames. Apesar disso, focamos aqui em Python pelo forte ecossistema formado em Data Science e pela maturidade das ferramentas, além da facilidade de se escrever código na linguagem.

Pandas em APIs Ambev

Temos na Ambev planilhas responsáveis por calcular milhares de informações estratégicas e sistemas que calculam milhões de dados de para a companhia. Essas ferramentas foram estabelecidas em um contexto onde haviam poucos produtos, o que está longe da realidade de hoje (e ainda mais do futuro) da companhia. Além disso, a tecnologia utilizada para os cálculos não é nada amigável.

Isso nos leva a dois dos grandes problemas que nosso produto nasceu para resolver:

  • O time de negócio tem dificuldade de alterar as fórmulas quando necessário
  • O sistema leva muito tempo para processar todos os dados

Partindo dessas necessidades construímos uma ferramenta que expõe as fórmulas através de notebooks jupyter e realiza os cálculos utilizando as APIs do Pandas.

Isso se provou útil não só como interface com o time de negócios, que deve fazer a manutenção das fórmulas, mas também para alguns métodos internos de nossa API: substituindo um laço em Python por operações em DataFrames Pandas reduzimos uma operação de 10 minutos para 10 segundos.

Este laço é responsável pela aplicação dos eventos no nosso mecanismo de Event Sourcing, onde mantemos todo histórico de alterações de dados das tabelas de entrada, e o cenário acima aconteceu quando tínhamos um total de 300 mil eventos para processar, um número modesto quando comparado ao esperado.

Mas então o que é performance, e o que importa?

Toda decisão de engenharia que traz grandes consequências para um projeto deve ser bem pensada, levando em consideração as necessidades do produto. Nos aproximar do brilhante ecossistema Python para Data Science foi uma escolha acertada considerando os requisitos citados do produto e já conseguimos alguns bons resultados.

Além do ganho do produto final, conseguimos construir um código inteligível, e nos apoiando em APIs que abstraem código baixo nível conseguimos entregar um bom desempenho sem termos que nos preocupar com detalhes como otimizações de cache, utilização de instruções SIMD e complexidade assintótica dos algoritmos.

E qual sua opinião? A performance entregue por Python vale a pena?

Os códigos utilizados estão disponíveis em https://github.com/cmillani/python-performance

--

--