Codes Algo Ruim Vai Acontecer - 🚨 CÓDIGOS ALGO RUIM VAI ACONTECER 🚨 SOMETHING BAD WILL HAPPEN CODES 🚨 ...
🚨 CÓDIGOS ALGO RUIM VAI ACONTECER 🚨 SOMETHING BAD WILL HAPPEN CODES 🚨 ...

O problema dos algoritmos mal escritos no dia a dia

Você já viu código que parece funcionar na teoria mas vai travar todo o sistema quando colocar em produção. Achei que ia escrever sobre isso de forma genérica, mas acabei me lembrando de um projeto específico onde isso quase me custou o emprego. Era uma API de recomendação que usava um algoritmo de ordenação mal configurado, e o tempo de resposta ia de 200ms para algo entre 8 e 14 segundos quando o dataset passava de 50 mil registros. O responsável tinha usado um bubble sort por engano em vez de um quicksort ou mergesort. Simplesmente copiou o primeiro exemplo de ordenação que encontrou num tutorial sem prestar atenção à complexidade. Isso é codes algo ruim vai acontecer, e a maioria das pessoas subestima até sentir na pele o resultado.

Como identificar um algoritmo ruim antes que ele destrua seu sistema

O primeiro sinal é sempre a complexidade de tempo. Se você vê loops aninhados sem uma razão clara, está provavelmente olhando para O(n²) ou pior. Uma vez, num sistema de processamento de imagens, encontrei um laço duplo que percorria toda a matriz de pixels duas vezes para fazer uma operação que poderia ser resolvida com uma única passagem e algumas variáveis temporárias. O resultado: um processamento que levava 45 segundos num batch de 1000 imagens quando deveria levar menos de 2. A correção foi simples mas exigiu entender o que o código realmente fazia, não apenas o que ele parecia fazer na superfície. Outro indicador é a ausência de testes de carga. Algoritmos bons resistem a pressão. Algoritmos ruins só mostram suas falhas quando o tráfego aumenta. Eu costumo rodar benchmarks mínimos antes de qualquer deploy. Sem isso, você está torcendo.

Práticas para evitar problemas

A solução mais óbvia é usar bibliotecas padrão da linguagem em vez de reimplementar algoritmos do zero. Python tem o Timsort via sorted(). JavaScript tem Array.sort() que usa um mergesort híbrido. C++ tem std::sort. Usar implementações próprias de algoritmos básicos é uma das causas mais comuns de códigos algo ruim vai acontecer em projetos reais. O segundo ponto é a análise de complexidade antes de escrever. Pegue papel e caneta. Desenhe o fluxo. Conte quantas operações seu algoritmo faz em relação ao tamanho da entrada. Se a resposta for "não sei", você tem um problema.

👉 Clique no botão abaixo para saber mais sobre o assunto!

Também vale a pena usar profiling. No meu caso do sistema de recomendação, o profiler do Python mostrou claramente que 87% do tempo de execução estava sendo gasto na função de ordenação. Sem esse dado, eu poderia ter gasto horas tentando otimizar outra parte do código que nem era o gargalo. Ferramentas como cProfile, py-spy ou até mesmo println timestamps em pontos estratégicos já resolvem 80% dos casos.

A armadilha que ninguém conta

O algoritmo "mais eficiente" teoricamente não é sempre a melhor escolha prática. Encontrei um projeto onde a equipe optou por um radix sort por ser O(n) em teoria, mas na prática o overhead de memória e a constante multiplicadora tornavam o negócio 3x mais lento que um quicksort bem implementado para os dados específicos que estavam processando. Dados pequenos, estrutura cache-friendly, e acesso sequencial valem mais do que notação assintótica bonita no papel. Isso quer dizer que você precisa testar com dados reais do seu domínio, não apenas confiar na teoria. O que funciona em StackOverflow nem sempre funciona na sua base de produção.

Quando o algoritmo ruim já está no código

Se você herdar um sistema com problemas, o caminho mais seguro é refatorar por partes. Não tente reescrever tudo de uma vez. Identifique o gargalo principal com profiling, otimize essa função específica, meça o ganho, e só então avance para o próximo ponto. Fiz isso numa aplicação de análise financeira onde o gargalo era uma busca linear num vetor não ordenado. Transformar esse vetor num HashSet reduziu a busca de O(n) para O(1) e cortou o tempo total do relatório de 3 minutos para 8 segundos. Se o algoritmo em si é fundamentalmente inadequado para o problema — como usar recursão sem memoization para calcular Fibonacci —, a refatoração pode exigir reescrever a lógica inteira. Nesse caso, escreva uma versão nova lado a lado com a antiga, faça testes de comparação de resultado, e só depois faça o switch. Código legado funciona até funcionar mal, e quando para de funcionar, você prefere ter um plano B pronto.

O problema é que raramente as pessoas têm tempo para fazer isso direito. O prazo aperta, a pressão do produto chega, e o código ruim continua rodando. Esse é o ciclo vicioso que faz codes algo ruim vai acontecer repetidamente em projetos por aí. O melhor que você pode fazer é criar o hábito de questionar a eficiência do código antes de mergear, mesmo que seja apenas uma olhada rápida nos loops e chamadas de função mais críticas.