Cómo comparar la eficiencia del script PHP

131

Quiero saber cuál es la mejor manera de comparar mis scripts PHP. No importa si es un trabajo cron, o una página web o un servicio web.

Sé que puedo usar microtime, pero ¿realmente me está dando el tiempo real de un script PHP?

Quiero probar y comparar diferentes funciones en PHP que hacen lo mismo. Por ejemplo, preg_matchvs strposo domdocumentvs preg_matcho preg_replace vs str_replace`

Ejemplo de una página web:

<?php
// login.php

$start_time = microtime(TRUE);

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

$end_time = microtime(TRUE);

echo $end_time - $start_time;

Esto generará: 0.0146126717 (varía todo el tiempo, pero ese es el último que obtuve). Esto significa que tomó aproximadamente 0.015 ejecutar el script PHP.

¿Hay una mejor manera?

eric
fuente
Lea este artículo: rakesh.sankar-b.com/2011/01/12/echo-print-which-is-fast-php - Espero que sea útil .
Rakesh Sankar
44
0.015 segundos. La velocidad promedio de parpadeo de un ojo es 0.3 segundos. ¿Realmente, realmente, realmente necesita mejorar esa velocidad? ¿Puedo preguntar por qué?
Ben
44
@ben, ese es un ejemplo, tengo páginas que se cargan en 0.8 segundos con más de 50,000 visitantes por hora. Necesito asegurarme de que la página se cargue rápido
Eric
8
@MarcB Amazon aparentemente probó y descubrió que un retraso de 100 ms causó una caída del 1% en las ventas. Eso podría ser miles de millones para un sitio grande como Amazon. highscalability.com/…
ceejayoz
1
@ceejayoz Sí, si usted es amazona, entonces ese es un gran problema, pero si no lo hace, tenga cuidado de simplemente perseguir tiempos de carga de páginas locos por el simple hecho de hacerlo. Amazon hizo su tarea y, por lo tanto, puede justificar fácilmente gastar X cantidad de horas hombre para reclamar la caída de Y en las ventas. ¡La lección aquí es hacer tu propia tarea!
James Butler

Respuestas:

123

Si realmente quiere comparar el código del mundo real, use herramientas como Xdebug y XHProf .

Xdebug es ideal para cuando trabajas en desarrollo / puesta en escena, y XHProf es una gran herramienta para la producción y es seguro ejecutarlo allí (siempre y cuando leas las instrucciones). Los resultados de una sola carga de página no serán tan relevantes como ver el rendimiento de su código mientras el servidor se ve forzado a hacer un millón de otras cosas y los recursos se vuelven escasos. Esto plantea otra pregunta: ¿tiene un cuello de botella en la CPU? ¿RAM? I / O?

También debe mirar más allá del código que está ejecutando en sus scripts para ver cómo se sirven sus scripts / páginas. ¿Qué servidor web estás usando? Como ejemplo, puedo hacer que nginx + PHP-FPM supere seriamente a mod_php + Apache, que a su vez es derrotado por servir contenido estático utilizando un buen CDN.

¿Lo siguiente a considerar es para qué está tratando de optimizar?

  • ¿Es la velocidad con la que la página representa en el navegador de los usuarios la prioridad número uno?
  • ¿El objetivo es enviar cada solicitud al servidor lo más rápido posible con el menor consumo de CPU?

Al primero se le puede ayudar haciendo cosas como comprimir todos los recursos enviados al navegador, pero hacerlo (en algunas circunstancias) podría alejarlo aún más de lograr el último.

Con suerte, todo lo anterior puede ayudar a mostrar que las pruebas de 'laboratorio' cuidadosamente aisladas no reflejarán las variables y los problemas que encontrará en la producción, y que debe identificar cuál es su objetivo de alto nivel y luego qué puede hacer para llegar allí, antes de descender por la ruta de optimización micro / prematura al infierno .

James Butler
fuente
66
Si esto realmente responde a su pregunta, Eric, siento que sus preguntas fueron redactadas incorrectamente (o tal vez solo lo leí mal). Según su pregunta, parecía que quería aislar diferentes métodos para hacer lo mismo en PHP e identificar cuál es el más rápido. Sin embargo, según las respuestas que aceptó y dio la recompensa, parece que estaba más interesado en hacer pruebas de carga de toda la pila web, que es algo completamente diferente.
Alec Gorge
Xdebug no admite scripts codificados con Ioncube. ¿Cómo se benchamrk esos guión?
BigSack
@BigSack Estás por tu cuenta allí, nunca he intentado perfilar algo que esté ofuscado de esa manera. Primero tendría una oportunidad con XHProf, ya que eso es relativamente fácil de ejecutar. Es posible que IonCube interfiera completamente con cualquier generador de perfiles que no sea de usuario.
James Butler
1
La declaración Nginx vs Apache está un poco sesgada. La mayoría descuida AllowOverideque Apache atraviese directorios completos para archivos .htaccess en cada solicitud. Esto solo saca a Apache de su propio camino.
B00MER
74

Para evaluar qué tan rápido se ejecuta su script completo en el servidor, hay muchas herramientas que puede usar. Primero asegúrese de que su script (preg_match vs strpos, por ejemplo) tenga que generar los mismos resultados para calificar su prueba.

Puedes usar:

Libro de zeus
fuente
30

Querrá ver Xdebug y, más específicamente, las capacidades de creación de perfiles de Xdebug .

Básicamente, habilita el generador de perfiles, y cada vez que carga una página web crea un archivo cachegrind que se puede leer con WinCacheGrind o KCacheGrind .

Xdebug puede ser un poco complicado de configurar, así que aquí está la sección relevante de mi php.inipara referencia:

[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

Y aquí hay una captura de pantalla de un .outarchivo en WinCacheGrind :

ingrese la descripción de la imagen aquí

Eso debería proporcionar amplios detalles sobre cuán eficiente es su script PHP. Desea enfocarse en las cosas que toman la mayor cantidad de tiempo. Por ejemplo, podría optimizar una función para tomar la mitad de la cantidad de tiempo, pero sus esfuerzos se verían mejor optimizando una función que se llama docenas si no cientos de veces durante una carga de página.

Si tiene curiosidad, esta es solo una versión antigua de un CMS que escribí para mi propio uso.

Garganta de Alec
fuente
8
parece muy complicado, no entiendo nada
eric
¿Qué parte no entiendes? ¿La configuración o el análisis de los datos?
Alec Gorge
1
así la configuración que no, que nunca funcionará en mi servidor pero los datos, todas sus cajas pequeñas no puedo leer
Eric
13
porque no uso windows
eric
2
+1 para XDebug + KCacheGrind. Es realmente útil y sorprendentemente fácil de instalar y usar. He estado usándolo durante bastante tiempo, una bonificación adicional que obtienes; una vez que te familiarices con él, puedes usar KCacheGrind con Valgrind (+ memgrind / callgrind) para perfilar muchos más idiomas (y no solo el tiempo de CPU).
XzKto
16

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

Permite definir pasos en el código e informa el tiempo, el uso de memoria, la carga del servidor, etc. entre dos pasos.

Algo como:

    $appgati->Step('1');

    // Do some code ...

    $appgati->Step('2');

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

Matriz de salida de muestra:

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
)
fotuzlab
fuente
2
Diseño de interfaz encantador (como veo que eres el autor), ¡gracias! (Y gracias por usar "ProperCase";) nombres de métodos (como SetMemory()) en lugar de la mixedCase()basura fea pero todavía ubicua , que de todos modos es prácticamente inútil en PHP. Probablemente eres demasiado viejo. ;))
Sz.
1
Totalmente anticuado, pero con un par de minutos lo convertí en algo agradable y útil (incluso en Windows). Trataré de ver si puedo hacer una solicitud de extracción.
Tomás González
7

Me gustaría ver en xhprof . No importa si se ejecuta en el cli o a través de otro sapi (como fpm o fcgi o incluso el módulo Apache).

La mejor parte de xhprof es que incluso es lo suficientemente apto para ejecutarse en producción. Algo que no funciona tan bien con xdebug (la última vez que lo verifiqué). xdebug tiene un impacto en el rendimiento y xhprof (no diría que no hay ninguno) se maneja mucho mejor.

Con frecuencia usamos xhprof para recolectar muestras con tráfico real y luego analizar el código desde allí.

No es realmente un punto de referencia en términos de tiempo y todo eso, aunque también lo hace. Simplemente hace que sea muy fácil analizar el tráfico de producción y luego profundizar hasta el nivel de función php en el callgraph recopilado.

Una vez que se compila y carga la extensión, comienza a generar perfiles en el código con:

xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);

Para detener:

$xhprof_data = xhprof_disable();

Luego guarde los datos en un archivo o base de datos, lo que sea que flote en su boath y no interrumpa el tiempo de ejecución habitual. Asignamos esto de forma asíncrona a S3 para centralizar los datos (para poder ver todas las ejecuciones de todos nuestros servidores).

El código en github contiene una carpeta xhprof_html que se descarga en el servidor y con una configuración mínima, puede visualizar los datos recopilados y comenzar a profundizar.

HTH!

Hasta que
fuente
3

Póngalo en un forbucle para hacer cada cosa 1,000,000 de veces para obtener un número más realista. Y solo inicie el temporizador justo antes del código que realmente desea comparar, luego registre la hora de finalización justo después (es decir, no inicie el temporizador antes del session_start().

También asegúrese de que el código sea idéntico para cada función que desee comparar, con la excepción de la función que está cronometrando.

La forma en que se ejecuta el script (cronjob, php desde la línea de comandos, Apache, etc.) no debería marcar la diferencia, ya que solo está cronometrando la diferencia relativa entre la velocidad de las diferentes funciones. Por lo tanto, esta relación debería permanecer igual.

Si la computadora en la que está ejecutando el benchmark tiene muchas otras cosas sucediendo, esto podría afectar los resultados del benchmark si se produce un aumento en el uso de CPU o memoria de otra aplicación mientras se ejecuta su benchmark. Pero mientras tenga muchos recursos de sobra en la computadora, no creo que esto sea un problema.

Alasdair
fuente
1

Un buen comienzo es usar xdebugs profiler http://xdebug.org/docs/profiler

Tal vez no sea lo más fácil de configurar y usar, pero una vez que lo pone en marcha, los grandes volúmenes de datos y la facilidad de visualización son irremplazables.

cabra
fuente
0

Eric

Te estás haciendo la pregunta equivocada. Si su script se está ejecutando en ~ 15 mSeg, entonces su tiempo es irrelevante. Si ejecuta en un servicio compartido, la activación de la imagen PHP tomará ~ 100 mSeg, leyendo en los archivos de secuencia de comandos ~ 30-50 mSec si está completamente en caché en el servidor, posiblemente 1 o más segundos si se carga desde una granja NAS de back-end. Los retrasos en la red al cargar los muebles de la página pueden agregar muchos segundos.

El problema principal aquí es la percepción del tiempo de carga de los usuarios: cuánto tiempo tiene que esperar entre hacer clic en el Enlace y obtener una página completamente renderizada. Eche un vistazo a Google Page Speed, que puede usar como extensión Ff o Chrome, y a la documentación de Pagespeed que analiza en profundidad cómo obtener un buen rendimiento de la página. Siga estas pautas e intente obtener mejores puntajes en su página que 90/100. (La página de inicio de google tiene un puntaje de 99/100 al igual que mi blog). Esta es la mejor manera de obtener un buen rendimiento percibido por el usuario.

TerryE
fuente
0

También es bueno vigilar su código PHP y hacer una verificación cruzada con este enlace , para asegurarse de que su propia codificación no perturbe potencialmente el rendimiento de la aplicación.

Ritesh Aryal
fuente