web-dev-qa-db-fra.com

Comment évaluer l'efficacité du script PHP

Je veux savoir quel est le meilleur moyen de comparer mes scripts PHP. Peu importe s'il s'agit d'un travail cron, d'une page Web ou d'un service Web.

Je sais que je peux utiliser microtime, mais me donne-t-il vraiment le temps réel d'un script PHP?

Je veux tester et comparer différentes fonctions dans PHP qui font la même chose. Par exemple, preg_match vs strpos ou domdocument vs preg_match ou 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 produira: 0.0146126717 (varie tout le temps - mais c’est le dernier que j’ai eu). Cela signifie qu'il a fallu environ 0.015 pour exécuter le script PHP.

Y a-t-il un meilleur moyen?

117
eric

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

Xdebug est idéal pour travailler avec dev/staging et XHProf est un excellent outil pour la production et il est sûr de l'exécuter là-bas (tant que vous lisez les instructions). Les résultats d'un chargement de page unique ne seront pas aussi pertinents que de voir comment votre code fonctionne alors que le serveur est en train de faire des millions de choses et que les ressources deviennent rares. Cela soulève une autre question: êtes-vous un goulot d'étranglement sur le processeur? RAM? I/O?

Vous devez également regarder au-delà du code que vous utilisez dans vos scripts pour voir comment vos scripts/pages sont servis. Quel serveur utilisez-vous? Par exemple, je peux faire en sorte que nginx + PHP-FPM exécute sérieusement mod_php + Apache, ce qui est critiqué pour la diffusion de contenu statique à l'aide d'un bon CDN.

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

  • La vitesse à laquelle la page s'affiche dans le navigateur de l'utilisateur est-elle la priorité numéro un?
  • L'objectif est-il de renvoyer chaque requête au serveur le plus rapidement possible tout en consommant le moins de ressources processeur possible?

Les premiers peuvent être aidés en faisant des choses comme gzipper toutes les ressources envoyées au navigateur, mais cela pourrait (dans certaines circonstances) vous éloigner de la réalisation de ces derniers.

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 votre objectif de haut niveau et ensuite ce que vous pouvez faire pour y parvenir. avant d’abandonner la micro/optimisation prématurée route vers l’enfer .

119
James Butler

Pour évaluer la rapidité d'exécution de votre script complet sur le serveur, vous pouvez utiliser de nombreux outils. Premièrement, assurez-vous que votre script (preg_match vs strpos par exemple) doit générer les mêmes résultats pour qualifier votre test.

Vous pouvez utiliser:

71
Book Of Zeus

Vous voudrez regarder Xdebug et plus précisément capacités de profilage de Xdebug .

En gros, 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 alors voici la section pertinente de mon php.ini Pour 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 fichier .out Dans WinCacheGrind :

enter image description here

Cela devrait fournir de nombreux détails sur l'efficacité de votre PHP le script. Vous voulez cibler les éléments qui prennent le plus de temps. Par exemple, vous pouvez optimiser une fonction pour qu'elle consomme deux fois moins temps, mais vos efforts seraient mieux servis en optimisant une fonction qui s'appelle des dizaines sinon des centaines de fois lors du chargement d'une page.

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

26
Alec Gorge

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

Il permet de définir des étapes dans le code et de rapporter 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
)
16
fotuzlab

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

La meilleure chose à propos de xhprof est qu'il est même suffisamment en forme pour être utilisé 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 ce qui concerne le fait que cela vous donne un temps et tout ça, bien que ça le fasse aussi. 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 que l'extension est 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();

Enregistrez ensuite les données dans un fichier ou une base de données - tout ce qui flotte dans votre esprit et n'interrompt pas l'exécution habituelle. Nous poussons cela de manière asynchrone vers S3 pour centraliser les données (afin de pouvoir visualiser 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 en profondeur.

HTH!

7
Till

Placez-le dans une boucle for pour que chaque opération soit effectuée 1 000 000 fois afin d'obtenir un nombre plus réaliste. Et ne démarrez le chronomètre 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 le chronomètre avant la session_start().

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

La façon dont le script est exécuté (cronjob, php de ligne de commande, Apache, etc.) ne devrait pas faire de différence, car vous ne faites que chronométrer la différence relative entre la vitesse des différentes fonctions. Donc, ce rapport devrait rester le même.

Si l'ordinateur sur lequel vous exécutez le test de performance a beaucoup d'autres activités en cours, cela pourrait affecter les résultats du test de performance s'il se produit une pointe d'utilisation du processeur ou de la mémoire d'une autre application pendant l'exécution de votre test de performance. Mais tant que vous avez beaucoup de ressources à épargner sur l'ordinateur, je ne pense pas que ce sera un problème.

3
Alasdair

Un bon début utilise xdebugs profiler http://xdebug.org/docs/profiler

Ce n’est peut-être pas la chose la plus facile à configurer et à utiliser, mais une fois que vous l’avez démarré, les énormes quantités de données et la facilité de visualisation sont irremplaçables.

1
goat

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

0
Ritesh Aryal

Eric,

Vous vous posez la mauvaise question. Si votre script s'exécute dans ~ 15 ms, son heure est en grande partie hors de propos. Si vous utilisez un service partagé, alors PHP l’activation de l’image prendra environ 100 ms, lecture des fichiers de script environ 30 à 50 ms si elle est entièrement mise en cache sur le serveur, éventuellement 1 seconde ou plus si elle est en cours. chargé depuis un serveur NAS ferme. Les retards du réseau lors du chargement de la page peuvent ajouter beaucoup de secondes.

Le problème principal ici est la perception du temps de chargement par les utilisateurs: combien de temps faut-il attendre entre le moment où ils cliquent sur le lien et l’obtention d’une page entièrement rendue. Regardez Google Page Speed que vous pouvez utiliser comme FF ou chrome), ainsi que la documentation de Pagespeed qui explique en détail comment obtenir de bonnes performances de page. Suivez ces consignes et essayez d’obtenir un score de page supérieur à 90/100 (la page d’accueil de Google marque 99/100, comme le fait mon blog). C’est le meilleur moyen d’obtenir de bonnes performances perçues par les utilisateurs.

0
TerryE

Ma réponse provient de: https://stackoverflow.com/a/28868536/306656

<?php
function yourFunction(){
  echo 'Code Im benchmarking';
}

$time_start = microtime(true);

$times=0;               // This couldn't be tough
while($times<1000)
{
   yourFunction();
   $times++;
}


$time_end = microtime(true);
$time = $time_end - $time_start;

echo "Did yourFunction in $time seconds\n";
?>

Changez simplement le code de votre fonction en repère.

0
Jeff Luyet