Um conhecimento abrangente dos problemas que deterioram o desempenho e formas de melhorá-lo permite ao desenvolvedor maior rapidez na hora de lidar com questões desse tipo e um nível elevado de criticidade ao escolher a opção que melhor atenda ao contexto da aplicação.
Além disso, nesse artigo há comentários e considerações acerca dos debates mais comuns envolvendo performance que, muitas vezes, parecem inconclusivos.
Um dos requisitos não funcionais mais lembrados durante o levantamento de requisitos é a performance do sistema, que pode ser definida como o tempo que o software demora para realizar uma determinada tarefa.
Para alguns domínios, como o varejo, o tempo de execução é crucial para que o software seja aceito e implantado em produção, afinal, é inaceitável que um cliente demore mais do que alguns segundos para realizar um pagamento em uma loja ou que o sistema demore alguns minutos para iniciar uma nova compra.
Nesses domínios, quando o desempenho da aplicação não atinge os requisitos mínimos exigidos, a performance pode gerar muitos prejuízos. Além do varejo, existem muitos outros domínios que dependem de um tempo de execução baixo, como home brokers (negociação de papéis em bolsa de valores) e sistemas de saúde. Nesses casos, problemas de performance podem causar imensos danos financeiros e até riscos à saúde humana.
Independente do domínio, o sistema deve ter um tempo de resposta aceitável. Mesmo que o domínio não seja crítico, um tempo de resposta muito longo pode frustrar os usuários e fazer com que o sistema seja visto como sem qualidade, visto que a performance é um forte atributo de qualidade percebido pelos usuários do software.
As próximas seções discutirão conceitos relevantes sobre o desempenho de aplicações, a relação entre performance e clareza de código, técnicas para escrever um código performático, técnicas para otimizar o código existente e considerações sobre diversos pontos da codificação que têm alguma relação com o desempenho e fazem parte do escopo do desenvolvedor.
Métricas de desempenho
Os requisitos de performance são, muitas vezes, tratados sem o devido cuidado. Não raro, em especificações de requisitos, são documentados com frases cuja interpretação é genérica ou fora da realidade como, por exemplo, “o sistema deve realizar a tarefa de forma rápida”.
Em casos como este, o que significa ser rápido? Qual o tempo de processamento é aceitável? Qual volume de dados processados é aceitável para determinado tempo de processamento? É preciso definir em termos quantitativos os números de desempenho, ter uma meta concreta e plausível de alcançar de acordo com o volume de dados tratado pela aplicação.
Desenvolvendo para o desempenho
Durante o desenvolvimento existem três abordagens comumente utilizadas para atender aos requisitos de performance em um projeto:
- Definir o tempo de execução de forma unitária: consiste em definir, para cada componente de software (método, classe ou subsistema) o tempo de execução aceitável para o mesmo. Durante o tempo de desenvolvimento, o desempenho do componente não pode exceder o limite definido para ele;
- Desenvolver de forma otimizada: consiste em desenvolver o software levando em consideração questões de desempenho em todos os momentos e em todas as partes do código, de forma que o software seja desenvolvido já atendendo aos requisitos de performance. Não é uma abordagem muito atraente, pois espalha pelo código melhorias de performance, o que torna o código como um todo mais difícil para trabalhar;
- Desenvolver primeiro e otimizar depois: consiste em desenvolver o software seguindo as boas práticas de codificação sem se preocupar com a performance. Depois do software desenvolvido, a otimização é feita por meio de refatorações até que o desempenho requerido seja atingido.
O código de alto desempenho é naturalmente mais complexo e não necessariamente segue os princípios da orientação a objetos como alta coesão e baixo acoplamento.
Geralmente o código performático ignora a baixa coesão ao realizar muitas tarefas em um único trecho de código em nome do desempenho, assim como o baixo acoplamento, que é ignorado pela redução de delegação no código. A relação entre código de qualidade e código performático é apresentada com mais detalhes na próxima seção.
Refatoração x Desempenho
Refatoração e desempenho têm dois objetivos completamente diferentes. Refatoração se preocupa com a conformidade do código às boas práticas de desenvolvimento, com o intuito de facilitar manutenções futuras, de forma que o código escrito seja fácil de ler, de entender e de modificar. Desempenho, por outro lado, diz respeito à performance do código, ao quão rápido ele irá executar a sua tarefa. Geralmente um código refatorado não é performático e vice-versa.
Segundo Martin Fowler, “o segredo do software rápido, em todos os contextos excetuando-se software de tempo real, é escrever software ajustável primeiro e então ajustá-lo para uma velocidade suficiente”.
Ou seja, é mais vantajoso desenvolver o código seguindo as boas práticas de desenvolvimento e depois realizar as modificações para o desempenho. Isso acontece devido ao fato de que a maioria dos programas gasta a maior parte do seu tempo em uma pequena fração do código.
O princípio de Pareto (princípio 80/20)
afirma que 80% das consequências advêm de 20%
das causas. Esse princípio pode
ser aplicado para validar a escolha de desenvolver primeiro código limpo
primeiro e otimizar depois. Nem todas as linhas de código que deterioram o
desempenho da aplicação, mas ...