Comment évaluer l'efficacité du script PHP

131

Je veux savoir quelle est la meilleure façon de comparer mes scripts PHP. Peu importe qu'il s'agisse d'un travail cron, d'une page Web ou d'un service Web.

Je sais que je peux utiliser microtime mais est-ce que cela me donne vraiment le temps réel d'un script PHP?

Je souhaite tester et comparer différentes fonctions de PHP qui font la même chose. Par exemple, preg_matchvs strposou domdocumentvs preg_matchou preg_replace vs str_replace`

Exemple de page Web:

<?php
// login.php

$start_time = microtime(TRUE);

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

$end_time = microtime(TRUE);

echo $end_time - $start_time;

Cela affichera: 0.0146126717 (varie tout le temps - mais c'est le dernier que j'ai). Cela signifie qu'il a fallu environ 0,015 pour exécuter le script PHP.

Y a-t-il un meilleur moyen?

Eric
la source
Lisez cet article: rakesh.sankar-b.com/2011/01/12/echo-print-which-is-fast-php - J'espère que cela aide.
Rakesh Sankar
4
0,015 seconde. La vitesse moyenne de clignotement d'un œil est de 0,3 seconde. Avez-vous vraiment, vraiment, vraiment besoin d'améliorer cette vitesse, puis-je vous demander pourquoi?
Ben
4
@ben c'est un exemple, j'ai des pages qui se chargent en 0,8 seconde avec plus de 50k visiteurs par heure, je dois m'assurer que la page se charge rapidement
Eric
8
@MarcB Amazon a apparemment testé et constaté qu'un retard de 100 ms entraînait une baisse de 1% des ventes. Cela pourrait représenter des milliards pour un grand site comme Amazon. highscalability.com
ceejayoz
1
@ceejayoz Oui, si vous êtes Amazon, c'est un gros problème, mais si ce n'est pas le cas, méfiez-vous des temps de chargement de page insensés pour le plaisir. Amazon a fait ses devoirs et peut donc facilement justifier de dépenser X heures de travail pour récupérer Y baisse des ventes. La leçon ici est de faire vos propres devoirs!
James Butler

Réponses:

123

Si vous souhaitez réellement évaluer le code du monde réel, utilisez des outils tels que Xdebug et XHProf .

Xdebug est idéal lorsque vous travaillez en dev / staging, et XHProf est un excellent outil pour la production et vous pouvez l'exécuter en toute sécurité ici (tant que vous lisez les instructions). Les résultats d'un seul chargement de page ne seront pas aussi pertinents que de voir comment votre code fonctionne alors que le serveur est martelé pour faire un million d'autres choses également et que les ressources deviennent rares. Cela soulève une autre question: goulot d'étranglement sur le processeur? RAM? E / S?

Vous devez également regarder au-delà du code que vous exécutez dans vos scripts pour voir comment vos scripts / pages sont servis. Quel serveur Web utilisez-vous? À titre d'exemple, je peux faire en sorte que nginx + PHP-FPM surpasse sérieusement mod_php + Apache, qui à son tour est détruit pour la diffusion de contenu statique en utilisant un bon CDN.

La prochaine chose à considérer est ce pour quoi vous essayez d'optimiser?

  • La vitesse à laquelle la page s'affiche dans le navigateur des utilisateurs est-elle la priorité numéro un?
  • L'objectif est-il de renvoyer chaque demande au serveur le plus rapidement possible avec la plus petite consommation de processeur?

Le premier peut être aidé en faisant des choses comme gzipper toutes les ressources envoyées au navigateur, mais cela pourrait (dans certaines circonstances) vous éloigner davantage de la réalisation du second.

Espérons que tout ce qui précède peut aider à montrer que des tests de laboratoire soigneusement isolés ne refléteront pas les variables et les problèmes que vous rencontrerez en production, et que vous devez identifier quel est votre objectif de haut niveau et ce que vous pouvez faire pour y arriver, avant de prendre la route de la micro / optimisation prématurée vers l'enfer .

James Butler
la source
6
Si cela répond vraiment à votre question Eric, je pense que vos questions ont été mal formulées (ou peut-être que je l'ai juste mal lu). Sur la base de votre question, il semblait que vous vouliez isoler différentes méthodes pour faire la même chose en PHP et identifier laquelle est la plus rapide. Cependant, sur la base des réponses que vous avez acceptées et que vous avez donné la prime, il semble que vous étiez plus intéressé par les tests de charge de l'ensemble de la pile Web - ce qui est complètement différent.
Alec Gorge
Xdebug ne prend pas en charge les scripts encodés Ioncube. Comment benchamrk ces script?
BigSack
@BigSack Vous êtes un peu seul là-bas, je n'ai jamais essayé de profiler quoi que ce soit qui soit obscurci comme ça. J'aurais d'abord une photo avec XHProf car c'est relativement facile à utiliser. Vous constaterez peut-être qu'IonCube interfère complètement avec tout profileur non utilisateur.
James Butler
1
La déclaration Nginx vs Apache est un peu biaisée. La plupart négligent le AllowOveridefait qu'Apache traverse des répertoires entiers pour les fichiers .htaccess à chaque demande. Cela seul éloigne Apache de son propre chemin.
B00MER
74

Pour évaluer la vitesse à laquelle votre script complet s'exécute sur le serveur, il existe de nombreux outils que vous pouvez utiliser. Assurez-vous d'abord que votre script (preg_match vs strpos par exemple) doit produire les mêmes résultats afin de qualifier votre test.

Vous pouvez utiliser:

Livre de Zeus
la source
30

Vous voudrez vous pencher sur Xdebug et plus spécifiquement, les capacités de profilage de Xdebug .

Fondamentalement, vous activez le profileur et chaque fois que vous chargez une page Web, il crée un fichier cachegrind qui peut être lu avec WinCacheGrind ou KCacheGrind .

Xdebug peut être un peu difficile à configurer, voici donc la section pertinente de mon php.inipour référence:

[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

Et voici une capture d'écran d'un .outfichier dans WinCacheGrind :

entrez la description de l'image ici

Cela devrait fournir de nombreux détails sur l'efficacité de votre script PHP. Vous voulez cibler les choses qui prennent le plus de temps. Par exemple, vous pouvez optimiser une fonction pour prendre la moitié du temps, mais vos efforts seraient mieux servis en optimisant une fonction appelée des dizaines, voire des centaines de fois pendant le chargement d'une page.

Si vous êtes curieux, c'est juste une ancienne version d'un CMS que j'ai écrit pour mon propre usage.

Gorges d'Alec
la source
8
semble très compliqué, je ne comprends rien
eric
Quelle partie ne comprenez-vous pas? La configuration ou l'analyse des données?
Alec Gorge
1
eh bien la configuration non, cela ne fonctionnera jamais sur mon serveur mais les données, ce sont toutes de petites boîtes que je ne peux pas lire
eric
13
parce que je n'utilise pas Windows
eric
2
+1 pour XDebug + KCacheGrind. Il est vraiment utile et étonnamment facile à installer et à utiliser. Je l'utilise depuis un certain temps, un bonus supplémentaire que vous obtenez - celui que vous devenez familier avec lui, vous pouvez utiliser KCacheGrind avec Valgrind (+ memgrind / callgrind) pour profiler beaucoup plus d'autres langues (et pas seulement le temps CPU).
XzKto
16

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

Il permet de définir des étapes dans le code et rapporte l'heure, l'utilisation de la mémoire, la charge du serveur, etc. entre deux étapes.

Quelque chose comme:

    $appgati->Step('1');

    // Do some code ...

    $appgati->Step('2');

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

Exemple de tableau de sortie:

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
la source
2
Belle conception d'interface (comme je vois que vous êtes l'auteur), grats! (Et merci d'utiliser "ProperCase";) des noms de méthodes (comme SetMemory()) au lieu de la mixedCase()merde laide mais toujours omniprésente , ce qui est pratiquement inutile de toute façon en PHP. Vous êtes probablement trop vieux. ;))
Sz.
1
Totalement obsolète mais avec quelques minutes, je l'ai transformé en quelque chose de gentil et utile (même sous Windows). Je vais essayer de voir si je peux faire une pull request.
Tomas Gonzalez
7

Je me pencherais sur xhprof . Peu importe qu'il soit exécuté sur le cli ou via un autre sapi (comme fpm ou fcgi ou même le module Apache).

La meilleure partie de xhprof est qu'il est même suffisamment en forme pour être exécuté en production. Quelque chose qui ne fonctionne pas aussi bien avec xdebug (la dernière fois que j'ai vérifié). xdebug a un impact sur les performances et xhprof (je ne dirais pas qu'il n'y en a pas) gère beaucoup mieux.

Nous utilisons fréquemment xhprof pour collecter des échantillons avec un trafic réel, puis analyser le code à partir de là.

Ce n'est pas vraiment une référence en termes de temps et tout cela, même si c'est aussi le cas. Il est simplement très facile d'analyser le trafic de production, puis de descendre au niveau de la fonction php dans le callgraph collecté.

Une fois l'extension compilée et chargée, vous démarrez le profilage dans le code avec:

xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);

Arrêter:

$xhprof_data = xhprof_disable();

Ensuite, enregistrez les données dans un fichier ou une base de données - tout ce qui fait flotter votre bateau et n'interrompt pas l'exécution habituelle. Nous le poussons de manière asynchrone vers S3 pour centraliser les données (pour pouvoir voir toutes les exécutions de tous nos serveurs).

Le code sur github contient un dossier xhprof_html que vous videz sur le serveur et avec une configuration minimale, vous pouvez visualiser les données collectées et commencer à explorer.

HTH!

Till
la source
3

Mettez-le en forboucle pour faire chaque chose 1 000 000 de fois pour obtenir un nombre plus réaliste. Et ne démarrez la minuterie que juste avant le code que vous voulez réellement comparer, puis enregistrez l'heure de fin juste après (c'est-à-dire ne démarrez pas la minuterie avant le session_start().

Assurez-vous également que le code est identique pour chaque fonction que vous souhaitez évaluer, à l'exception de la fonction que vous chronométrez.

La façon dont le script est exécuté (cronjob, php depuis la ligne de commande, Apache, etc.) ne devrait pas faire de différence puisque vous ne chronométrez que la différence relative entre la vitesse des différentes fonctions. Ce ratio devrait donc rester le même.

Si l'ordinateur sur lequel vous exécutez le benchmark a beaucoup d'autres choses en cours, cela pourrait affecter les résultats du benchmark en cas de pic d'utilisation du processeur ou de la mémoire d'une autre application pendant que votre benchmark est en cours d'exécution. Mais tant que vous avez beaucoup de ressources à dépenser sur l'ordinateur, je ne pense pas que ce sera un problème.

Alasdair
la source
1

Un bon début consiste à utiliser xdebugs profiler http://xdebug.org/docs/profiler

Ce n'est peut-être pas la chose la plus simple à configurer et à utiliser, mais une fois que vous l'avez fait, les volumes de données et la facilité de visualisation sont irremplaçables.

chèvre
la source
0

Eric,

Vous vous posez la mauvaise question. Si votre script s'exécute en ~ 15 msec, son heure est en grande partie sans importance. Si vous exécutez sur un service partagé, l'activation de l'image PHP prendra ~ 100 mSec, la lecture des fichiers de script ~ 30-50 mSec s'il est entièrement mis en cache sur le serveur, éventuellement 1 seconde ou plus s'il est chargé depuis une batterie de serveurs NAS backend. Les retards du réseau lors du chargement du mobilier de page peuvent ajouter beaucoup de secondes.

Le principal problème ici est la perception des utilisateurs du temps de chargement: combien de temps doit-il attendre entre le clic sur le lien et l'obtention d'une page entièrement rendue. Jetez un œil à Google Page Speed que vous pouvez utiliser comme extension Ff ou Chrome, et à la documentation Pagespeed qui explique en profondeur comment obtenir de bonnes performances de page. Suivez ces consignes et essayez d'obtenir des scores de page supérieurs à 90/100. (La page d'accueil de Google obtient 99/100, tout comme mon blog). C'est le meilleur moyen d'obtenir de bonnes performances perçues par l'utilisateur.

TerryE
la source
0

Il est également bon de garder les yeux sur votre code PHP et de vérifier avec ce lien , afin de vous assurer que votre codage lui-même ne perturbe pas potentiellement les performances de l'application.

Ritesh Aryal
la source