Categories
Engenharia de software

A falácia da otimização prematura

“A otimização prematura é a raiz de todo o mal”. Quantas vezes você já ouviu essa frase? Eu mesmo já disse isso aqui nesse mesmo blog e já falei essa frase para várias outras pessoas. O problema, como já apontavam os sábios budistas, é que as pessoas acabam levando as coisas ao extremo… Para alguns desenvolvedores, como a otimização é a raiz de todo o mal ela deve ser evitada a qualquer custo e ao longo dos anos o sentido da frase acabou virando simplesmente “nunca otimize seu código”.

O criador dessa frase famosa foi Tony Hoare e Donald Knuth foi o responsável por torná-la popular. O que as pessoas não param para pensar é que quando essa frase foi dita, em 1975, o contexto era completamente diferente. O que Hoare e Knuth estavam realmente falando é que os engenheiros de software da época deveriam se preocupar com outras coisas mais importantes (como um bom design de algorítmos e boas implementações desses algorítmos) antes de se preocupar com micro-otimizações como a quantidade de ciclos de CPU que um determinado comando consome. A história toda é bem interessante e recomendo a leitura completa.

Hoje em dia os tipos de software que desenvolvemos são completamente diferentes. A capacidade computacional das máquinas é diferente, as arquiteturas dos sistemas, a quantidade de usuários… Temos bancos inteiros totalmente computadorizados com milhões de transações simultâneas acontecendo e essas trasações não podem falhar ou alguém perde dinheiro em algum lugar. Temos sistemas na internet que suportam milhões de usuários trocando mensagens o tempo todo. Enfim, precisamos considerar aspectos bem diferentes.

Eoin Woods, membro da IASA, publicou um artigo sobre o que ele acredita que sejam os 10 maiores erros de arquitetura cometidos em projetos. O item número 7 é “Assumir requisitos de performance e escalabilidade”. Ele acredita que você deve começar a considerar aspectos de performance e escalabilidade desde cedo porque isso ajudará a aumentar a sua confiança de que não há nenhum bicho de sete cabeças que na última hora vai arruinar qualquer possibilidade da sua aplicação ir para produção. Os requisitos de performance de uma aplicação devem ser conhecidos, estudados e levados em consideração desde o início do desenvolvimento.

Robert Annet do Coding The Architecture cita um outro exemplo do que pode acontecer quando você assume certas informações erradas no desenvolvimento. Ele também conclui que todos os desenvolvedores devem sempre estar cientes da arquitetura de um sistema e como isso afeta o que está sendo desenvolvido. Faz muita diferença, por exempo, se uma aplicação rodará em cluster ou não.

Resumindo, eu discordo de quem diga que um software não deve ser otimizado antes mesmo de ser desenvolvido. Há casos e casos. Veja a minha situação: quando eu desenvolvo sistemas na Globo.com, como é que eu posso ignorar o fato de que o sistema será acessado por milhões de usuários? No nosso último projeto, por exemplo, uma das premissas era que o player de vídeos fosse ultra-compacto (menor quantidade de bytes possível) já que ele seria baixado por qualquer usuário que fosse ver o vídeo e não poderia afetar o carregamento da página. Se não fosse isso poderíamos acabar tendo um daqueles arquivos Flash de 2 MB que quando você acessa a página tem que esperar 2 minutos para carregar – a experiência do usuário fica um lixo.

Porém também acho que temos que tomar cuidado para não exagerar na dose. Otimizações são boas quando elas são realmente necessárias.

Já cansei de ver desenvolvedores sacrificarem o design de uma aplicação por causa de performance ou otimizações que eram completamente desnecessárias. Quando você tem requisitos de performance claros como os que eu citei acima é óbvio que você tem que levá-los em consideração. Mas a grande maioria das aplicações certamente não atende milhões de usuários nem se você somar 10 anos de acesso! Então o que acaba acontecendo é que ao invés de se preocupar com desenvolver software de qualidade, bem testado, modular e com design decente muita gente acaba desenvolvendo software desnecessariamente otimizado e difícil de entender e modificar. A não ser que você tenha requisitos não-funcionais bem claros e definidos a prioridade sempre deve ser por um bom design, código legível, extensível e esse tipo de coisa.

Otimizar cedo ou não, sempre vai ser um assunto controverso. Normalmente esse tipo de coisa envolve julgar uma série de fatores técnicos e de negócio. Concluindo, é essencial que a equipe de desenvolvimento tenha bom senso ao tomar essas decisões. Nunca otimizar ou sempre otimizar são abordagens completamente equivocadas. Como dizem os budistas, “prefira sempre o caminho do meio”.