Introdução: por que seu código PHP está lento?
Todo desenvolvedor já passou pela situação em que um site em PHP começa a ficar lento. As páginas carregam em 5 a 10 segundos, o banco de dados "cai" e o servidor sufoca com a carga. Na maioria das vezes, o problema não está no hardware, mas no código — nos chamados "gargalos" (bottlenecks).
Profiling é o processo de coletar dados sobre quanto tempo e memória cada parte do seu script consome. Sem profiling, você trabalha no escuro, tentando adivinhar o que está deixando a aplicação lenta. Neste artigo, vamos ver como encontrar e eliminar gargalos no código PHP usando ferramentas modernas.
1. Principais ferramentas de profiling para PHP
Existem várias ferramentas consolidadas para profiling em PHP. Vamos ver as mais populares:
1.1. Xdebug — o clássico do profiling
Xdebug é uma extensão para PHP que oferece recursos poderosos de depuração e profiling. Ela gera arquivos de trace que podem ser analisados em utilitários especiais (como KCacheGrind ou Webgrind).
Instalação do Xdebug (Ubuntu/Debian):
sudo apt install php-xdebug
sudo phpenmod xdebug
Configuração no php.ini:
xdebug.mode = profile
xdebug.output_dir = /tmp/profiling
xdebug.profiler_output_name = cachegrind.out.%t.%p
Após isso, cada requisição criará um arquivo de perfil na pasta /tmp/profiling. Você pode abri-lo no KCacheGrind (Linux) ou QCacheGrind (Windows/Mac).
1.2. Blackfire.io — profiler em nuvem
Blackfire é um serviço comercial da SensioLabs (criadores do Symfony). Ele oferece uma interface web amigável, integração com CI/CD e recomendações automáticas de otimização.
Instalação via Composer:
composer require blackfire/php-sdk
Exemplo de uso no código:
<?php
$probe = Blackfire::createProbe();
// Seu código
$probe->close();
?>
O Blackfire mostra não apenas o tempo de execução, mas também a quantidade de consultas SQL, chamadas de funções e consumo de memória. Ideal para projetos grandes.
1.3. Funções nativas do PHP
Para uma diagnose rápida, você pode usar funções nativas:
microtime(true)— mede o tempo de execução de um trecho de código.memory_get_usage()— consumo atual de memória.memory_get_peak_usage()— pico de consumo de memória.
Exemplo:
<?php
$start = microtime(true);
// Seu código
$time = microtime(true) - $start;
echo "Executado em: " . round($time, 4) . " seg";
?>
2. Gargalos típicos no código PHP
Depois de configurar o profiler, é hora de saber no que prestar atenção. Aqui estão os problemas mais comuns:
2.1. Consultas N+1 ao banco de dados
Isso é clássico: em um loop, dados relacionados são buscados com consultas separadas. Exemplo de código ruim:
<?php
$users = $db->query("SELECT * FROM users");
foreach ($users as $user) {
$posts = $db->query("SELECT * FROM posts WHERE user_id = {$user['id']}");
// Processamento...
}
?>
Solução: uma única consulta com JOIN:
<?php
$data = $db->query("SELECT u.*, p.* FROM users u LEFT JOIN posts p ON u.id = p.user_id");
?>
2.2. Loops ineficientes
Loops aninhados com arrays grandes são assassinos de performance. Exemplo:
<?php
foreach ($bigArray as $outer) {
foreach ($bigArray as $inner) {
// Complexidade O(n²)
}
}
?>
Use tabelas hash (arrays associativos) para acelerar a busca:
<?php
$map = [];
foreach ($bigArray as $item) {
$map[$item['id']] = $item;
}
?>