Maneira mais simples de criar um perfil de um script PHP


289

Qual é a maneira mais fácil de criar um perfil de script PHP?

Eu adoraria colocar algo que me mostre um despejo de todas as chamadas de função e quanto tempo elas levaram, mas também estou bem em colocar algo em torno de funções específicas.

Eu tentei experimentar a função microtime :

$then = microtime();
myFunc();
$now = microtime();

echo sprintf("Elapsed:  %f", $now-$then);

mas isso às vezes me dá resultados negativos. Além disso, é muito problemático espalhar isso por todo o meu código.


7
ei Mark, confira este comentário para ajudá-lo a resolver os comentários negativos: ro.php.net/manual/en/function.microtime.php#99524
Mina

16
Esse comentário vinculado por @Midiane não faz sentido. Se pareceu resolver o problema do comentarista, deve ter sido uma coincidência. Usando apenas microtime()vai levar a expressões às vezes avaliando como: "0.00154800 1342892546" - "0.99905700 1342892545", que irá avaliar como: 0.001548 - 0.999057. Você pode usar microtime( TRUE )para evitar esse problema, como apontado por @luka.
JMM 21/07

Respostas:


104

A extensão PECL APD é usada da seguinte maneira:

<?php
apd_set_pprof_trace();

//rest of the script
?>

Depois, analise o arquivo gerado usando pprofp.

Exemplo de saída:

Trace for /home/dan/testapd.php
Total Elapsed Time = 0.00
Total System Time  = 0.00
Total User Time    = 0.00


Real         User        System             secs/    cumm
%Time (excl/cumm)  (excl/cumm)  (excl/cumm) Calls    call    s/call  Memory Usage Name
--------------------------------------------------------------------------------------
100.0 0.00 0.00  0.00 0.00  0.00 0.00     1  0.0000   0.0009            0 main
56.9 0.00 0.00  0.00 0.00  0.00 0.00     1  0.0005   0.0005            0 apd_set_pprof_trace
28.0 0.00 0.00  0.00 0.00  0.00 0.00    10  0.0000   0.0000            0 preg_replace
14.3 0.00 0.00  0.00 0.00  0.00 0.00    10  0.0000   0.0000            0 str_replace

Aviso: a versão mais recente do APD é datada de 2004, a extensão não é mais mantida e tem vários problemas de compatibilidade (consulte os comentários).


19
A extensão APD está quebrada no php 5.4.
Skynet

Em resposta ao user457015, consegui fazê-lo funcionar em um site executando o wordpress 3.8.1 e o PHP 5.3.10 e parecia funcionar muito bem.
Supernovah

1
@Supernovah, user457015 disse PHP 5.4. Ele não disse que estava quebrado no PHP 5.3.
Magnus #

@ user1420752 Estou executando o 5.3.27 e também não está executando lá. Eu recebo um erro de função indefinido.
Fractaly 13/08/16

2
A última versão do APD é de 2004 (!) Ele não funciona com o PHP 7. Ao tentar instalar o PHP 5 com pecl install apd, ele fornece uma mensagem de erro sobre "config.m4". Parece que você precisa instalá-lo da fonte, o que eu ainda não tentei. Sério, não existe uma ferramenta moderna e atualizada de criação de perfil baseada em CLI para PHP que é instalada com o Homebrew, requer configuração mínima e fornece saída facilmente legível por humanos?
forthrin 29/08/16

267

Você quer xdebug, eu acho. Instale-o no servidor, ligue-o, bombeie a saída pelo kcachegrind (para linux) ou wincachegrind (para windows) e ele mostrará alguns gráficos bonitos que detalham os horários exatos, contagens e uso de memória (mas você precisa de outra extensão para isso).

É demais, sério: D


6
Achei isso muito mais fácil de implementar do que a solução APD. Mas talvez seja porque, por algum motivo, o APD não tenha sido compilado corretamente no meu sistema. Também os gráficos de kcachegrind eram tão bonitos quanto o prometido.
Wxs

1
@EvilPuppetMaster, você precisa compilar o php com --enable-memory-limit ou usar uma versão php mais moderna. Veja xdebug.org/docs/basic#xdebug_memory_usage
mercutio

52
O xdebug + webgrind rapidamente se tornou minha arma de escolha para criação de perfil rápido e fácil. code.google.com/p/webgrind
xkcd150 27/04/10

6
xdebug + xdebug_start_trace () + xdebug_stop_trace () = vitória
quano

3
Foi muito fácil começar a trabalhar no Windows com o XAMPP. Já tinha netbeans configurados para xdebug. A única coisa que você precisa fazer é alterar uma configuração de xdebug no php.ini para xdebug.profiler_output_name = "cachegrind.out.% T-% s" ou nenhuma saída será gerada. Requer reinicialização do apache.
iniciante_

97

Não são necessárias extensões, basta usar essas duas funções para criar um perfil simples.

// Call this at each point of interest, passing a descriptive string
function prof_flag($str)
{
    global $prof_timing, $prof_names;
    $prof_timing[] = microtime(true);
    $prof_names[] = $str;
}

// Call this when you're done and want to see the results
function prof_print()
{
    global $prof_timing, $prof_names;
    $size = count($prof_timing);
    for($i=0;$i<$size - 1; $i++)
    {
        echo "<b>{$prof_names[$i]}</b><br>";
        echo sprintf("&nbsp;&nbsp;&nbsp;%f<br>", $prof_timing[$i+1]-$prof_timing[$i]);
    }
    echo "<b>{$prof_names[$size-1]}</b><br>";
}

Aqui está um exemplo, chamando prof_flag () com uma descrição em cada ponto de verificação e prof_print () no final:

prof_flag("Start");

   include '../lib/database.php';
   include '../lib/helper_func.php';

prof_flag("Connect to DB");

   connect_to_db();

prof_flag("Perform query");

   // Get all the data

   $select_query = "SELECT * FROM data_table";
   $result = mysql_query($select_query);

prof_flag("Retrieve data");

   $rows = array();
   $found_data=false;
   while($r = mysql_fetch_assoc($result))
   {
       $found_data=true;
       $rows[] = $r;
   }

prof_flag("Close DB");

   mysql_close();   //close database connection

prof_flag("Done");
prof_print();

A saída fica assim:

Iniciar
   0.004303
Conectar ao DB
   0.003518
Executar consulta
   0.000308
Recuperar dados
   0.000009
Fechar DB
   0.000049
Concluído


37

Postando minha referência na SO Documentation beta, que está ficando offline.

Criação de perfil com o XDebug

Uma extensão para PHP chamada Xdebug está disponível para auxiliar na criação de perfil de aplicativos PHP , bem como na depuração em tempo de execução. Ao executar o criador de perfil, a saída é gravada em um arquivo em um formato binário chamado "cachegrind". Os aplicativos estão disponíveis em cada plataforma para analisar esses arquivos. Nenhuma alteração no código do aplicativo é necessária para executar essa criação de perfil.

Para habilitar a criação de perfil, instale a extensão e ajuste as configurações do php.ini. Algumas distribuições Linux vêm com pacotes padrão (por exemplo, php-xdebugpacote do Ubuntu ). Em nosso exemplo, executaremos o perfil opcionalmente com base em um parâmetro de solicitação. Isso nos permite manter as configurações estáticas e ativar o criador de perfil apenas conforme necessário.

# php.ini settings
# Set to 1 to turn it on for every request
xdebug.profiler_enable = 0
# Let's use a GET/POST parameter to turn on the profiler
xdebug.profiler_enable_trigger = 1
# The GET/POST value we will pass; empty for any value
xdebug.profiler_enable_trigger_value = ""
# Output cachegrind files to /tmp so our system cleans them up later
xdebug.profiler_output_dir = "/tmp"
xdebug.profiler_output_name = "cachegrind.out.%p"

Em seguida, use um cliente da Web para fazer uma solicitação ao URL do seu aplicativo que você deseja criar um perfil, por exemplo,

http://example.com/article/1?XDEBUG_PROFILE=1

À medida que a página é processada, ela será gravada em um arquivo com um nome semelhante a

/tmp/cachegrind.out.12345

Por padrão, o número no nome do arquivo é a identificação do processo que o escreveu. Isso é configurável com a xdebug.profiler_output_nameconfiguração.

Observe que ele gravará um arquivo para cada solicitação / processo PHP executado. Portanto, por exemplo, se você deseja analisar uma postagem de formulário, um perfil será gravado para a solicitação GET exibir o formulário HTML. O parâmetro XDEBUG_PROFILE precisará ser passado para a solicitação POST subsequente para analisar a segunda solicitação que processa o formulário. Portanto, ao criar um perfil, às vezes é mais fácil executar curl para postar um formulário diretamente.

Analisando a saída

Depois de gravado, o cache do perfil pode ser lido por um aplicativo como o KCachegrind ou o Webgrind . O PHPStorm, um popular IDE do PHP, também pode exibir esses dados de criação de perfil .

KCachegrind

O KCachegrind, por exemplo, exibirá informações, incluindo:

  • Funções executadas
  • Tempo de chamada, próprio e inclusivo das chamadas de função subsequentes
  • Número de vezes que cada função é chamada
  • Gráficos de chamadas
  • Links para código fonte

O que procurar

Obviamente, o ajuste de desempenho é muito específico para os casos de uso de cada aplicativo. Em geral, é bom procurar:

  • Chamadas repetidas para a mesma função que você não esperaria ver. Para funções que processam e consultam dados, essas podem ser as principais oportunidades para o cache do seu aplicativo.
  • Funções de execução lenta. Onde o aplicativo está gastando a maior parte do tempo? a melhor recompensa no ajuste de desempenho está focada nas partes do aplicativo que consomem mais tempo.

Nota : O Xdebug, e em particular seus recursos de criação de perfil, consomem muitos recursos e diminuem a execução do PHP. É recomendável não executá-los em um ambiente de servidor de produção.


3
Para completar a lista de ferramentas para analisar o cache do perfil: PhpStorm também tem uma ferramenta para visualizar o cache do perfil
peterchaula

1
@ Peter Esqueci PHPStorm tem esse recurso. Adicionei-o com um link para a documentação. Obrigado!
Matt S

Alguma maneira de obter um relatório de texto (não GUI) diretamente no servidor?
Alexander Shcheblikin

1
@ Mark, você pode marcar isso como resposta, por favor. A resposta atual estava desatualizada, mesmo quando postada e não funciona há muitos anos. Isso funciona e não conheço um método melhor.
Mawg diz que restabelece Monica em

24

Se subtrair microtimes fornecer resultados negativos, tente usar a função com o argumento true( microtime(true)). Com true, a função retorna um float em vez de uma string (como acontece se for chamada sem argumentos).


24

Honestamente, vou argumentar que o uso do NewRelic para criação de perfil é o melhor.

É uma extensão PHP que parece não diminuir o tempo de execução e eles fazem o monitoramento para você, permitindo uma pesquisa decente. Na versão cara, eles permitem drill down pesado (mas não podemos pagar pelo modelo de preços).

Mesmo assim, mesmo com o plano gratuito / padrão, é óbvio e simples onde está a maioria das frutas baixas. Eu também gosto que ele também pode dar uma idéia sobre as interações com o banco de dados.

captura de tela de uma das interfaces ao criar um perfil


16
A New Relic parece promissora, com certeza. No entanto, a parte "Divulgação dos dados do aplicativo" de sua Política de Privacidade me repeliu instantaneamente. Imho, compartilhar partes do código-fonte proprietário com terceiros é um pouco demais.
Cengiz

8
Não estamos aqui em defesa deles, mas parece que "Dados do Aplicativo" são apenas informações de desempenho e informações de configuração do sistema, não o código-fonte do aplicativo.
David Shields

Fir meu novo relíquia está mostrando meu "WebTransaction", como 99% do tempo, e não tem a conta pro para "ApplicationTraces"
Karthik T

1
tente se inscrever em: newrelic.com/rackspace <deve dar-lhe "padrão" de graça
zeroasterisk

15

Perfil do pobre homem, sem extensões necessárias. Suporta perfis aninhados e porcentagem do total:

function p_open($flag) {
    global $p_times;
    if (null === $p_times)
        $p_times = [];
    if (! array_key_exists($flag, $p_times))
        $p_times[$flag] = [ 'total' => 0, 'open' => 0 ];
    $p_times[$flag]['open'] = microtime(true);
}

function p_close($flag)
{
    global $p_times;
    if (isset($p_times[$flag]['open'])) {
        $p_times[$flag]['total'] += (microtime(true) - $p_times[$flag]['open']);
        unset($p_times[$flag]['open']);
    }
}

function p_dump()
{
    global $p_times;
    $dump = [];
    $sum  = 0;
    foreach ($p_times as $flag => $info) {
        $dump[$flag]['elapsed'] = $info['total'];
        $sum += $info['total'];
    }
    foreach ($dump as $flag => $info) {
        $dump[$flag]['percent'] = $dump[$flag]['elapsed']/$sum;
    }
    return $dump;
}

Exemplo:

<?php

p_open('foo');
sleep(1);
p_open('bar');
sleep(2);
p_open('baz');
sleep(3);
p_close('baz');
sleep(2);
p_close('bar');
sleep(1);
p_close('foo');

var_dump(p_dump());

Rendimentos:

array:3 [
  "foo" => array:2 [
    "elapsed" => 9.000766992569
    "percent" => 0.4736904954747
  ]
  "bar" => array:2 [
    "elapsed" => 7.0004580020905
    "percent" => 0.36841864946596
  ]
  "baz" => array:2 [
    "elapsed" => 3.0001420974731
    "percent" => 0.15789085505934
  ]
]

13

O PECL XHPROF também parece interessante. Possui interface HTML clicável para visualizar relatórios e documentação bastante direta . Ainda tenho que testá-lo.


Parece que não está recebendo muito amor. Última atualização em 2009, nenhum pacote PEAR para 5.3, 5.4 e além ...
dland 02/02

1
Facebook criou um garfo com apoio através de php 5.5 github.com/facebook/xhprof
borkencode

Verifique também este garfo, que propõe alguns ajustes adicionais: github.com/preinheimer/xhprof
Fedir RYKHTIK 04/04

O xhprof.io fornece GUI para dados coletados usando XHProf, além de capacidade de armazenar dados no banco de dados para fins de análise histórica. Eu sou o autor desta última implementação.
Gajus

10

Eu gosto de usar o phpDebug para criação de perfil. http://phpdebug.sourceforge.net/www/index.html

Ele gera todo o uso de tempo / memória para qualquer SQL usado, bem como para todos os arquivos incluídos. Obviamente, ele funciona melhor em códigos abstraídos.

Para perfis de função e classe, usarei microtime()+ get_memory_usage()+ get_peak_memory_usage().



6

Para benchmarking, como no seu exemplo, eu uso o pacote Pear Benchmark . Você define marcadores para medição. A classe também fornece alguns auxiliares de apresentação ou você pode processar os dados como achar melhor.

Na verdade, eu o envolvi em outra classe com um método __destruct. Quando um script sai, a saída é registrada via log4php no syslog; portanto, tenho muitos dados de desempenho para trabalhar.


3

O XDebug não é estável e nem sempre está disponível para uma determinada versão do php. Por exemplo, em alguns servidores, eu continuo executando o php-5.1.6, - é o que vem com o RedHat RHEL5 (e o btw ainda recebe atualizações para todas as questões importantes), e o XDebug recente nem compila com este php. Então, acabei mudando para o depurador DBG. O benchmarking php fornece tempo para funções, métodos, módulos e até linhas.


2

Vocês todos deveriam definitivamente conferir este novo perfil de php.

https://github.com/NoiseByNorthwest/php-spx

Redefine a maneira como os criadores de perfil php coletam e apresentam o resultado. Em vez de emitir apenas um número total de chamadas de função específicas e o tempo total gasto para executá-lo - o PHP-SPX apresenta toda a linha do tempo da execução de solicitações de uma maneira perfeitamente legível. Abaixo está a tela da GUI que ela fornece.

insira a descrição da imagem aqui

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.