Como avaliar a eficiência do script PHP


131

Quero saber qual é a melhor maneira de comparar meus scripts PHP. Não importa se um trabalho cron, página da web ou serviço da web.

Eu sei que posso usar microtime, mas é realmente me dando o tempo real de um script PHP?

Quero testar e comparar funções diferentes no PHP que fazem a mesma coisa. Por exemplo, preg_matchvs strposou domdocumentvs preg_matchou preg_replace vs str_replace`

Exemplo de uma página da web:

<?php
// login.php

$start_time = microtime(TRUE);

session_start(); 
// do all my logic etc...

$end_time = microtime(TRUE);

echo $end_time - $start_time;

Isso produzirá: 0.0146126717 (varia o tempo todo - mas esse é o último que recebi). Isso significa que foram necessários 0,015 ou mais para executar o script PHP.

Existe uma maneira melhor?



4
0,015 segundos. A velocidade média de um olho piscando é de 0,3 segundos. Você realmente precisa melhorar essa velocidade, posso perguntar por quê?
Ben

4
@ Ben, que é um exemplo, eu tenho páginas que carrega em 0,8 segundos, com mais de 50k visitantes por hora que eu preciso para se certificar de que a página carrega rápido
eric

8
O @MarcB Amazon aparentemente testou e descobriu que o atraso de 100ms causou uma queda de 1% nas vendas. Isso pode ser bilhões para um site grande como o Amazon. highscalability.com/…
ceejayoz

1
@ceejayoz Sim, se você é amazon, esse é um grande problema, mas se você não tiver cuidado, basta procurar tempos de carregamento de páginas insanos por causa disso. A Amazon fez a lição de casa e, portanto, pode facilmente justificar o gasto de X horas-homem para recuperar a queda de Y nas vendas. A lição aqui é fazer sua própria lição de casa!
James Butler

Respostas:


123

Se você realmente deseja comparar o código do mundo real, use ferramentas como Xdebug e XHProf .

O Xdebug é ótimo para quando você está trabalhando em desenvolvimento / estadiamento, e o XHProf é uma ótima ferramenta para produção e é seguro executá-lo lá (desde que você leia as instruções). Os resultados de qualquer carregamento de uma única página não serão tão relevantes quanto ver o desempenho do seu código enquanto o servidor está sendo martelado para fazer um milhão de outras coisas e os recursos se tornam escassos. Isso levanta outra questão: você está engarrafando na CPU? RAM? E / S?

Você também precisa olhar além do código que está executando em seus scripts para saber como seus scripts / páginas estão sendo veiculados. Qual servidor da web você está usando? Como exemplo, eu posso fazer com que o nginx + PHP-FPM execute seriamente o mod_php + Apache, que por sua vez é criticado por fornecer conteúdo estático usando uma boa CDN.

A próxima coisa a considerar é o que você está tentando otimizar?

  • A velocidade com que a página renderiza no navegador do usuário é a prioridade número um?
  • Obter cada solicitação para o servidor é descartado o mais rápido possível, com o menor consumo de CPU, o objetivo?

O primeiro pode ser ajudado fazendo coisas como compactar todos os recursos enviados para o navegador, mas isso pode (em algumas circunstâncias) afastar você ainda mais do alcance do último.

Esperamos que todas as opções acima possam ajudar a mostrar que testes 'laboratoriais' cuidadosamente isolados não refletirão as variáveis ​​e os problemas que você encontrará na produção e que você deve identificar qual é seu objetivo de alto nível e o que pode fazer para chegar lá, antes de seguir a rota da micro / otimização prematura para o inferno .


6
Se isso realmente responder à sua pergunta, sinto que suas perguntas foram formuladas incorretamente (ou talvez eu apenas tenha lido errado). Com base na sua pergunta, parecia que você queria isolar métodos diferentes de fazer a mesma coisa no PHP e identificar qual é o mais rápido. No entanto, com base nas respostas que você aceitou e deu a recompensa, parece que você estava mais interessado em fazer testes de carga de toda a pilha da Web - o que é algo completamente diferente.
Alec Gorge,

O Xdebug não suporta scripts codificados em Ioncube. Como você benchamrk esses scripts?
BigSack 20/08/13

@ BigSack Você está meio que sozinho por lá, nunca tentei traçar um perfil de algo tão ofuscado assim. Eu teria uma chance com o XHProf primeiro, pois é relativamente fácil de executar. Você pode achar que o IonCube interfere completamente com qualquer profiler que não seja do usuário.
James Butler

1
A instrução Nginx vs Apache é um pouco tendenciosa. A maioria das negligências faz AllowOveridecom que o Apache percorra diretórios inteiros para arquivos .htaccess em cada solicitação. Isso por si só tira o Apache de seu próprio caminho.
B00MER 04/08/19


30

Você deve examinar o Xdebug e, mais especificamente, os recursos de criação de perfil do Xdebug .

Basicamente, você habilita o criador de perfil e, toda vez que carrega uma página da Web, ele cria um arquivo cachegrind que pode ser lido com o WinCacheGrind ou o KCacheGrind .

O Xdebug pode ser um pouco complicado de configurar, então aqui está a seção relevante do meu php.inipara referência:

[XDebug]
zend_extension = h:\xampp\php\ext\php_xdebug-2.1.1-5.3-vc6.dll
xdebug.remote_enable=true
xdebug.profiler_enable_trigger=1
xdebug.profiler_output_dir=h:\xampp\cachegrind
xdebug.profiler_output_name=callgrind.%t_%R.out

E aqui está uma captura de tela de um .outarquivo no WinCacheGrind :

insira a descrição da imagem aqui

Isso deve fornecer amplos detalhes sobre a eficácia do seu script PHP. Você deseja segmentar as coisas que levam mais tempo. Por exemplo, você pode otimizar uma função para levar metade da quantidade de tempo, mas seus esforços seriam mais úteis para otimizar uma função chamada dezenas, senão centenas de vezes durante o carregamento da página.

Se você estiver curioso, esta é apenas uma versão antiga de um CMS que escrevi para meu próprio uso.


8
parece muito complicado, eu não entendo nada
eric

Qual parte você não entende? A configuração ou análise dos dados?
Alec Gorge

1
bem a configuração não, isso nunca vai funcionar no meu servidor, mas os dados, seus todas as pequenas caixas eu não posso ler
eric

13
porque eu não uso o windows
eric

2
+1 para XDebug + KCacheGrind. É realmente útil e surpreendentemente fácil de instalar e usar. Eu uso esse software há algum tempo, um bônus adicional que você recebe - um que você se familiarize com ele, você pode usar o KCacheGrind com o Valgrind (+ memgrind / callgrind) para criar um perfil de muito mais outros idiomas (e não apenas o tempo da CPU).
XzKto

16

Tente https://github.com/fotuzlab/appgati

Permite definir etapas no código e relata tempo, uso de memória, carga do servidor etc. entre duas etapas.

Algo como:

    $appgati->Step('1');

    // Do some code ...

    $appgati->Step('2');

    $report = $appgati->Report('1', '2');
    print_r($report);

Matriz de saída de amostra:

Array
(
    [Clock time in seconds] => 1.9502429962158
    [Time taken in User Mode in seconds] => 0.632039
    [Time taken in System Mode in seconds] => 0.024001
    [Total time taken in Kernel in seconds] => 0.65604
    [Memory limit in MB] => 128
    [Memory usage in MB] => 18.237907409668
    [Peak memory usage in MB] => 19.579357147217
    [Average server load in last minute] => 0.47
    [Maximum resident shared size in KB] => 44900
    [Integral shared memory size] => 0
    [Integral unshared data size] => 0
    [Integral unshared stack size] => 
    [Number of page reclaims] => 12102
    [Number of page faults] => 6
    [Number of block input operations] => 192
    [Number of block output operations] => 
    [Number of messages sent] => 0
    [Number of messages received] => 0
    [Number of signals received] => 0
    [Number of voluntary context switches] => 606
    [Number of involuntary context switches] => 99
)

2
Adorável design de interface (como eu vejo você é o autor), grats! (E obrigado por usar o "ProperCase";) nomes de métodos (como SetMemory()) em vez da mixedCase()porcaria feia, mas ainda onipresente , que é praticamente inútil de qualquer maneira no PHP. Você provavelmente é muito velho. ;))
Sz.

1
Totalmente desatualizado, mas com alguns minutos eu o transformei em algo agradável e útil (mesmo no Windows). Vou tentar ver se posso fazer uma solicitação de recebimento.
Tomas Gonzalez

7

Gostaria de olhar para xhprof . Não importa se é executado no cli ou através de outro sapi (como fpm ou fcgi ou mesmo o módulo Apache).

A melhor parte do xhprof é que ele é adequado o suficiente para ser executado na produção. Algo que não funciona tão bem com o xdebug (da última vez que verifiquei). O xdebug afeta o desempenho e o xhprof (eu não diria que não exista) gerencia muito melhor.

Freqüentemente usamos o xhprof para coletar amostras com tráfego real e depois analisar o código a partir daí.

Não é realmente uma referência em termos de tempo e tudo mais, embora isso também ocorra. Isso facilita muito a análise do tráfego de produção e, em seguida, detalha o nível da função php no callgraph coletado.

Depois que a extensão é compilada e carregada, você começa a criar um perfil no código com:

xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);

Parar:

$xhprof_data = xhprof_disable();

Em seguida, salve os dados em um arquivo ou banco de dados - o que quer que flutue no seu caminho e não interrompa o tempo de execução normal. Enviamos isso de forma assíncrona para o S3 para centralizar os dados (para poder ver todas as execuções de todos os nossos servidores).

O código no github contém uma pasta xhprof_html que você despeja no servidor e, com uma configuração mínima, pode visualizar os dados coletados e começar a detalhar.

HTH!


3

Coloque-o em um forloop para fazer cada coisa 1.000.000 de vezes para obter um número mais realista. E inicie o cronômetro apenas antes do código que você realmente deseja comparar, depois grave o horário final logo após (ou seja, não inicie o cronômetro antes do session_start().

Verifique também se o código é idêntico para cada função que você deseja fazer benchmark, com exceção da função em que você está criando o tempo.

Como o script é executado (cronjob, php na linha de comando, Apache, etc.) não deve fazer diferença, pois você está cronometrando apenas a diferença relativa entre a velocidade das diferentes funções. Portanto, essa proporção deve permanecer a mesma.

Se o computador em que você está executando o benchmark tiver muitas outras coisas acontecendo, isso poderá afetar os resultados do benchmark, se ocorrer um aumento no uso da CPU ou da memória de outro aplicativo enquanto o benchmark estiver em execução. Mas desde que você tenha muitos recursos de sobra no computador, não acho que isso seja um problema.


1

Um bom começo é usar o xdebugs profiler http://xdebug.org/docs/profiler

Talvez não seja a coisa mais fácil de configurar e usar, mas depois que você obtém os volumes de dados e a facilidade de visualização é insubstituível.


0

Eric,

Você está se perguntando a pergunta errada. Se o seu script estiver sendo executado em ~ 15 mSec, o tempo será irrelevante. Se você executar em um serviço compartilhado, a ativação da imagem PHP levará ~ 100 mSec, lendo nos arquivos de script ~ 30-50 mSec se estiver totalmente em cache no servidor, possivelmente 1 ou mais segundos se estiver sendo carregado de um farm NAS de back-end. Atrasos na rede ao carregar os móveis da página podem adicionar muitos segundos.

O principal problema aqui é a percepção do usuário sobre o tempo de carregamento: quanto tempo ele ou ela deve esperar entre clicar no link e obter uma página totalmente renderizada. Dê uma olhada no Google Page Speed, que você pode usar como extensão Ff ou chrome, e na documentação do Pagespeed, que discute detalhadamente como obter um bom desempenho da página. Siga estas diretrizes e tente obter pontuações na página melhores que 90/100. (A página inicial do Google possui 99/100, assim como o meu blog). Essa é a melhor maneira de obter um bom desempenho percebido pelo usuário.


0

Também é bom manter os olhos no seu código PHP e fazer uma verificação cruzada com este link , para garantir que sua própria codificação não esteja prejudicando o desempenho do aplicativo.

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.