Tecnologia
Código que faz a diferença. Por que se preocupar com a eficiência dos algoritmos?
3 minutos de leitura
Recentemente, foi-me atribuída a tarefa de melhorar o tempo de carregamento de uma página em um projeto. A página listava informações sobre produtos que o cliente havia adquirido. Era apenas uma seção em que fazia uma requisição para o servidor e listava na tela os dados retornados.
Os usuários desse sistema sempre reclamaram dessa seção, pois atrasava todo o fluxo de trabalho deles, visto que precisavam acessar essa seção várias vezes ao dia, o que acabava impactando a produtividade deles, tendo, por vezes, que esperar alguns minutos para a aba carregar.
O tempo de carregamento da aba variava de aproximadamente 1 minuto para casos em que se tinha poucos itens e de 2 a 3 minutos para situações em que se tinha muitos itens. Por exemplo, ao tentar listar 2 linhas de produtos já adquiridos em uma das amostras que testei, o tempo de carregamento chegava aproximadamente a 1 minuto para carregar por completo.
Talvez você pense: “1 minuto nem demora tanto assim”. Mas, para quem utiliza a tela diariamente, ter que esperar 1 minuto para cada cadastro que acessar pode ser um pouco desanimador. Um usuário que precise entrar em pelo menos 30 cadastros ao longo do dia vai perder pelo menos 30 minutos do seu tempo esperando o sistema carregar.
Aos poucos, essa demora se torna uma bola de neve e acaba por impactar diretamente na produtividade do usuário. Pois, ao longo de uma semana ou mês, você perdeu horas de vida, só por conta de ter que esperar o tempo de carregamento.
Ao olhar mais de perto, notei que o problema era uma View no banco de dados que continha diversos “joins“. Um exemplo do que foi encontrado pode ser visto abaixo:
SELECT * FROM PRODUCTS_OF_CLIENTS PC
INNER JOIN PRODUCTS P ON PC.PRODUCT_ID = P.ID
INNER JOIN CLIENTS C ON C.ID = PC.CLIENT_ID
INNER JOIN CLIENT_ADDRESS CE ON C.ID = CE.CLIENT_ID
...
INNER JOIN PROCUTS_VALUES PV ON PV.PRODUCT_ID = P.ID
WHERE
P.STATUS = 1
AND P.TYPE IN (1, 2, 3)
AND PV.VALUES > 0
...
AND C.ID = ?
A consulta era imensa. Tinha muitas condições e junções. Um grande aglomerado. Passei um tempo lendo-a para entender todos os relacionamentos. Após isso, tive um insight e comecei a refatorar.
Um dos problemas que notei era que a maioria dos critérios adotados para aquela consulta não eram mais necessários. Algumas daquelas condições e junções estavam relacionadas a funcionalidades passadas do sistema que já não estavam mais vigentes na versão atual do software.
Dessa maneira, comecei a remover um por um. Condições que não faziam mais sentido eu removia. Dados que não eram exibidos na listagem eu removia. Junções que não faziam parte da busca eram retiradas.
No fim, o que era realmente necessário eram apenas 3 tabelas. Ficando algo como:
SELECT * FROM PRODUCTS_OF_CLIENTS PC
INNER JOIN PRODUCTS P ON PC.PRODUCT_ID = P.ID
INNER JOIN CLIENTS C ON C.ID = PC.CLIENT_ID
WHERE
P.STATUS = 1
AND C.ID = ?
Quando medi novamente a performance da tela, comemorei. O tempo de carregamento diminuiu mais da metade, passando de minutos para segundos. No caso da amostra em que tinha testado, foi de 1 minuto para 20 segundos. Recebi alguns feedbacks positivos sobre o resultado e com certeza economizei o tempo de vida de muitos usuários.
A correção era bem simples. No fim, a diferença para resolver o problema foi apenas uma ideia. Apenas uma nova forma de implementar a busca considerando o novo cenário. Nada complexo. Foi algo em que se fosse pensando em investimento/retorno valeu muito a pena. Em poucas vezes, deixei a tela muito mais rápida.
Isso me fez pensar sobre como um algoritmo pode ser um fator importante para influenciar a produtividade de uma empresa. Não pensamos com frequência, mas um algoritmo pode ser considerado uma tecnologia. Não por se tratar de algo derivado de uma linguagem de programação ou por estar ligado a computadores, mas por ter o potencial de agregar imenso valor em toda uma companhia, por ter a possibilidade de dar uma vantagem competitiva.
Imagine no caso de uma empresa de logística. Conseguir calcular a melhor rota para as entregas de mercadorias pode significar o sucesso ou o fracasso do negócio. Quanto melhor o algoritmo, menor será o custo de entrega e tempo.
Como programadores, estamos a todo momento escrevendo código e pensando em algoritmos. Precisamos ter em mente que apesar de nem sempre produzirmos o melhor possível, o que produzimos pode impactar uma cadeia de pessoas. Como no exemplo da consulta que citei acima, ela tirava por dia alguns minutos das pessoas. Isso afetava a produtividade delas.
Algoritmos ineficientes também podem afetar o financeiro da empresa. Por exemplo, um algoritmo ruim pode consumir mais recursos do servidor em que está alocado, o que pode elevar os custos para a empresa, impactando negativamente nos resultados contábeis, o que poderia levar a uma demissão para enxugar os custos.
Dessa maneira, devemos ter em alta estima a eficiência do código que escrevemos. Ao pensar em software, ao arquitetar uma nova solução ou ao escrever código, não criamos apenas a possibilidade de impactar nossos usuários, mas criamos a possibilidade de impactar todo o futuro de uma empresa.