CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 90

Otimização de Código – Codificação Performática e Produção de Sistemas Escaláveis

Tempo de Leitura: 8 Minutos

Todo desenvolvedor precisa ter a consciência de que é preciso otimizar o código desde o início da codificação. Seguir boas práticas é o ponto de partida para escrever um código otimizado e legível, além de veloz para ser executado e consumindo somente os recursos necessários de máquina. Separei 10 dicas de otimização de código para ajudar no aumento de performance, e se receber comentários, nos aprofundamos em comparativos de performance para a escolha técnica em situações de desenvolvimento de aplicações de ponta e de alta escalabilidade.

1. Use funções nativas
Sempre que possível, utilize as funções nativas da linguagem ao invés de escrever suas próprias funções para atingir um objetivo. Caso ainda não esteja totalmente familiarizado com a linguagem, procure no manual se a função que você quer existe. Muitas linguagens, principalmente as de script possuem bibliotecas de funções escritas em outras linguagens, que “rodam” mais próximas do hardware e são mais rápidas que uma série de instruções realizadas dentro da linguagem interpretada.

2. Prefira utilizar strings literais
Em algumas linguagens, o uso de Aspas simples ( ‘ ) é mais rápido que aspas duplas ( “ ) devido ao fato do interpretador, entender que quando você usa a aspa simples é um string literal, porém quando você utiliza aspas duplas, o compilador verifica se existe a presença de alguma variável dentro da string e a substitui pelo valor correspondente, e isto adiciona uma sobrecarga desnecessária em tempo de execução.

3. Use funções de string apropriadas, principalmente em análise de grandes conteúdos de texto
Várias linguagens definem funções que aparentemente podem ser usadas para trabalhar com textos e padrões de strings, por exemplo, o PHP define a função str_replace para substituir um texto por outro, e ela é mais rápida que o preg_replace, que usa uma expressão regular para localizar o texto, e exceto se realmente você precise localizar uma sequencia determinada em uma expressão regular, ela não deve ser usada pois para sua execução uma série de análises de expressões são feitas, mas a strtr é quatro vezes mais rápida que a str_replace pois não reprocessa a string para cada argumento, já que não faz retrabalho. Isso significa que se bem projetada a entrada, e os filtros, o trabalho de processamento pode ser bem menor.

4. Defina o valor para a variável
Analise o seguinte trecho de código:

for ($i = 0; $i<count($num); $i++) {
echo $num[$i];
}

Agora analise o proximo trecho que tem basicamente a mesma função:

$total = count($num);
for ($i = 0; $i<$total; $i++) {
echo $num[$i];
}

Quanto maior o tamanho do array $num, mais lento será o código de cima, pois a cada volta do loop, ele precisa executar a função count() para percorrer todos os elementos do array, se for um array associativo, a velocidade chega a ser 4 vezes menor que o segundo exemplo. E se você usar um foreach em um array associativo a performance é ainda maior. Se bem que arrays indexados são muito mais rápidos para serem processados.

5. Não crie Classes sem necessidade
Não crie Classes e Métodos até que seja realmente necessário e principalmente que possam ser reutilizados. Um dos grandes (na verdade enormes) problemas com frameworks é justamente algumas classes que já foram desenvolvidas por terceiros ou mesmo pelo framework com propósitos genéricos e que possuem dezenas e centenas de métodos, e você acaba importando a classe inteira, nestes casos, acaba sendo mais performático o uso de classes menores, ou mesmo a implementação de funções e estilo procedural para uso do recurso.
Na realidade, ambas as formas se bem produzidas não serão o gargalo do desempenho, importar um milhão de funções de um arquivo, ou um milhão de métodos dá praticamente na mesma, a diferença é que em OOP a organização acaba sendo melhor.

6. Feche a conexão
Adquira o hábito de fechar a conexão com o banco de dados; isto economiza memória, tanto no serviço do php quanto no lado do servidor de banco de dados. Indiferente da técnica usada, o fechamento de conexões, destruição de variáveis e sessões não mais usadas, faz parte da programação e da otimização do código. Uma outra boa prática e ter somente as conexões necessárias ao banco de dados, imagine que a cada consulta/procedimento implementado você faça uma conexão diferente, e não a feche, com poucos clientes simultâneos gerando requisições, você vai sobrecarregar seu banco de dados.

7. Reduza os acessos ao BD
Reduza a quantidade de acessos ao banco de dados. Faça consultas utilizando o menor número de conexões possível, e também trafegando o menor número e quantidade de dados necessários. Por exemplo:

$con = mysql_connect ("localhost", "username", "senha", "database");
if (mysql_connect_errno ()){
   echo "Falha ao conectar ao MySQL";
   mysql_connect_error ();
}

function insertValue ($ val) {
   mysql_query( "INSERT INTO TableX (id,valor) values ('', '$val' )" );
}

for ($i = 0; $i <99; $i++) {
// Invocando a função para inserir os dados
insertValue($i);
}
// Fechando a conexão como a melhor prática!
mysql_close ($con);

Neste código inserimos uma sequencia de dados de 0 a 99, e realizamos 100 operações no manco de dados.

$con = mysql_connect ("localhost", "user", "passwd", "database");
if (mysql_connect_errno ()) {
    echo "Falha ao conectar ao MySQL";
    mysql_connect_error ();
}

function insertValues ​​( $val ) {
    // Inserindo com todos os 99 valores, utilizando apenas um INSERT.
    $query = "INSERT INTO TableX ( ".implode(',', $val)." )";
    mysql_query ($con, $query);
}

$dados = array();
for ($i = 0; $i<99; $i++) {
    // Criação do vetor com os dados.
    $dados[] = $i;
}
// Invocando a função para inserir os dados
insertValues ​​($dados);
// Fechando a conexão como uma boa prática!
mysql_close ($con);

Neste segundo exemplo, você fez a mesma operação com somente 1 chamada ao banco de dados. O mesmo se aplica a selects, se você só precisa do nome e id de um cadastro com 100 colunas, não use um “select * from tablex” pois o volume de dados retornado vai ser muito maior que “select id,nome from tablex”. Pensando dessa maneira, reveja a necessidade de percorrer grandes quantidades de dados.

8. Use JSON
Use JSON em vez de XML sempre que trabalhar com aplicativos web. Existem funções nativas para trabalhar com JSON, como json_encode () e json_decode () e estas funções são extremamente rápidas, além de que no lado do cliente, os navegadores e linguagens vão trabalhar de maneira mais rápida com objetos JSON do que com XML devido a sua simplicidade.

9. Declare suas variáveis, e use sempre que possível retornos booleanos
Linguagens mais modernas e menos imperativas como PHP, PYTHON, NODE.JS, JS e uma série de outras permitem que você use variáveis declaradas em qualquer parte do código, porém essa prática não é indicada, principalmente em metodologias ágeis de desenvolvimento devido a falta de documentação.
Outro problema são os tipos de retorno, retornar um booleano ou um valor numérico é melhor que um valor string devido a forma como as linguagens fazem a comparação desses valores. Se você tem uma lista finita de elementos, ao invés de criar um array associativo (chave=>valor) prefira um array indexado que vai ser processado muito mais rapidamente pelo código.

Isso se aplica também a consultas e respostas do banco de dados, é muito comum receber uma resposta com por exemplo 100 registros de um banco de dados, por exemplo:

SELECT * from CLIENTES order by NomeCliente

Ao invés de uma listagem assim, prefira o uso paginado e também só dos campos que você precisa no momento, muito mais simples para o sistema e o banco de dados tratarem:

SELECT Id, NomeCompleto, CPF from clientes WHERE NomeCompleto LIKE 'Maria do%' limit 0,50

Esta segunda consulta poderia ser gerada automaticamente, ou caso precise de uma listagem de TODOS os clientes, use o sistema de paginação, como:

SELECT Id, NomeCompleto, CPF from clientes WHERE limit 50,50 order by NomeCompleto

Via de regra, exceto se você está exportando seus dados para uma outra aplicação, como o excell ou gerando um relatório complexo, dificilmente uma consulta vai ultrapassar os 200 registros, se constantemente isso está ocorrendo, verifique se não é hora de criar filtros mais complexos, ou, repensar a lógica que está gerando isso pois imagina quanto tempo o cliente vai perder analisando esses dados para localizar a informação específica.

10. Use técnicas de caching
Utilize cache para reduzir as conexões/carga ao banco de dados e a compilação do script. Uma boa opção para reduzir as conexões/carga ao banco de dados é o Memcache e o APC para o cache opcode e otimização do código intermediário.

Atualmente, com os servidores em nuvem e a disponibilidade de recursos a razoavelmente baixo custo, está se tornando muito comum, a produção de código de baixa qualidade, antes de aumentar as necessidades de hardware de um determinado sistema computacional, como a escalabilidade, é muito importante verificar se seu código está otimizado. Pois quando migramos para um ambiente virtualmente infinito, esse código mal projetado e ineficiente vai continuar ineficiente, gerando gastos e consumo de recursos desnecessários, que podem fazer com que o seu sistema possa acabar sendo abandonado e/ou substituído por opções mais eficientes.

A diferença entre um programador júnior e um sênior é justamente a qualidade do código produzido, e da otimização dos recursos que se tem em mãos. Portanto, se sua ideia é seguir carreira na área de desenvolvimento, aprender a melhor forma para fazer uma determinada tarefa é o melhor caminho. Uso de linguagens mais fortemente tipificadas como C/C++, JAVA, PYTHON é um ótimo caminho para se aprender a importância de cada parte do código e entender os recursos computacionais, portanto regras mais impositivas são um caminho para melhorar a qualidade dos seus códigos.

No próximo artigo, vamos falar sobre a otimização dos dados e dos bancos de dados. Deixe seu comentário ou sua dúvida, que temos imenso prazer em ajudar.