Question

Quelle est la manière la plus simple de profiler un script PHP ?

J'adorerais ajouter quelque chose qui me montre un aperçu de tous les appels de fonction et combien de temps ils ont pris, mais je suis également d'accord pour mettre quelque chose autour de fonctions spécifiques.

J'ai essayé d'expérimenter avec le microtime fonction:

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

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

mais cela me donne parfois des résultats négatifs.De plus, c'est très difficile de saupoudrer cela partout dans mon code.

Était-ce utile?

La solution

Le PECL-APD l'extension est utilisée comme suit :

<?php
apd_set_pprof_trace();

//rest of the script
?>

Ensuite, analysez le fichier généré en utilisant pprofp.

Exemple de sortie :

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

Avertissement:la dernière version d'APD date de 2004, l'extension n'est plus entretenu et présente divers problèmes de compatibilité (voir commentaires).

Autres conseils

Tu veux xdebug Je pense.Installez-le sur le serveur, allumez-le, pompez la sortie via kcachegrind (pour Linux) ou wincachegrind (pour Windows) et il vous montrera quelques jolis graphiques détaillant les horaires exacts, le nombre et l'utilisation de la mémoire (mais vous aurez besoin d'une autre extension pour cela).

Ça déchire, sérieusement :D

Aucune extension n'est nécessaire, utilisez simplement ces deux fonctions pour un profilage simple.

// 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>";
}

Voici un exemple, appelant prof_flag() avec une description à chaque point de contrôle, et prof_print() à la fin :

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();

Le résultat ressemble à ceci :

Commencer
   0.004303
Se connecter à la base de données
   0.003518
Effectuer une requête
   0.000308
Récupérer des données
   0.000009
Fermer la base de données
   0.000049
Fait

Publication croisée de ma référence de la version bêta de SO Documentation qui est hors ligne.

Profilage avec XDebug

Une extension PHP appelée Xdebug est disponible pour vous aider profilage des applications PHP, ainsi que le débogage d'exécution.Lors de l'exécution du profileur, la sortie est écrite dans un fichier au format binaire appelé « cachegrind ».Des applications sont disponibles sur chaque plateforme pour analyser ces fichiers. Aucune modification du code d’application n’est nécessaire pour effectuer ce profilage.

Pour activer le profilage, installez l'extension et ajustez les paramètres php.ini.Certaines distributions Linux sont livrées avec des packages standards (par ex.Ubuntu php-xdebug emballer).Dans notre exemple, nous exécuterons le profil éventuellement en fonction d'un paramètre de requête.Cela nous permet de conserver les paramètres statiques et d'activer le profileur uniquement en cas de besoin.

# 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"

Utilisez ensuite un client Web pour faire une demande à l'URL de votre application que vous souhaitez profiler, par ex.

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

Au fur et à mesure que la page est traitée, elle écrira dans un fichier portant un nom similaire à

/tmp/cachegrind.out.12345

Par défaut, le numéro dans le nom du fichier est l'identifiant du processus qui l'a écrit.Ceci est configurable avec le xdebug.profiler_output_name paramètre.

Notez qu’il écrira un fichier pour chaque requête/processus PHP exécuté.Ainsi, par exemple, si vous souhaitez analyser une publication de formulaire, un profil sera écrit pour la requête GET afin d'afficher le formulaire HTML.Le paramètre XDEBUG_PROFILE devra être transmis dans la requête POST suivante pour analyser la deuxième requête qui traite le formulaire.Par conséquent, lors du profilage, il est parfois plus facile d’exécuter curl pour POSTER directement un formulaire.

Analyser le résultat

Une fois écrit, le cache de profil peut être lu par une application telle que KCachegrind ou Webgrind.PHPStorm, un IDE PHP populaire, peut également afficher ces données de profilage.

KCachegrind

KCachegrind, par exemple, affichera des informations telles que :

  • Fonctions exécutées
  • Temps d'appel, à la fois lui-même et y compris les appels de fonction ultérieurs
  • Nombre de fois que chaque fonction est appelée
  • Graphiques d'appels
  • Liens vers le code source

Ce qu'il faut chercher

Évidemment, l’optimisation des performances est très spécifique aux cas d’utilisation de chaque application.En général, il est bon de rechercher :

  • Appels répétés à la même fonction que vous ne vous attendriez pas à voir.Pour les fonctions qui traitent et interrogent des données, cela pourrait constituer une excellente opportunité de mise en cache pour votre application.
  • Fonctions lentes.Où l’application passe-t-elle la plupart de son temps ?le meilleur gain en matière d’optimisation des performances consiste à se concentrer sur les parties de l’application qui consomment le plus de temps.

Note:Xdebug, et en particulier ses fonctionnalités de profilage, sont très gourmands en ressources et ralentissent l'exécution de PHP.Il est recommandé de ne pas les exécuter dans un environnement de serveur de production.

Si la soustraction de microtimes vous donne des résultats négatifs, essayez d'utiliser la fonction avec l'argument true (microtime(true)).Avec true, la fonction renvoie un float au lieu d'une chaîne (comme elle le fait si elle est appelée sans arguments).

Honnêtement, je vais dire que l'utilisation de NewRelic pour le profilage est la meilleure solution.

Il s'agit d'une extension PHP qui ne semble pas du tout ralentir l'exécution et qui effectue la surveillance pour vous, permettant une analyse approfondie.Dans la version coûteuse, ils permettent une analyse approfondie (mais nous ne pouvons pas nous permettre leur modèle de tarification).

Pourtant, même avec le plan gratuit/standard, il est évident et simple de savoir où se trouvent la plupart des fruits les plus faciles à trouver.J'aime aussi le fait que cela puisse également vous donner une idée sur les interactions avec la base de données.

screenshot of one of the interfaces when profiling

PECL XHPROF ça a l'air intéressant aussi.Il a interface HTML cliquable pour visualiser les rapports et assez simple Documentation.Cependant, je ne l'ai pas encore testé.

Profilage du pauvre, aucune extension requise.Prend en charge les profils imbriqués et le pourcentage du 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;
}

Exemple:

<?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());

Rendements :

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
  ]
]

J'aime utiliser phpDebug pour le profilage.http://phpdebug.sourceforge.net/www/index.html

Il affiche toute l'utilisation du temps et de la mémoire pour tout SQL utilisé ainsi que tous les fichiers inclus.Évidemment, cela fonctionne mieux sur du code abstrait.

Pour le profilage des fonctions et des classes, j'utiliserai simplement microtime() + get_memory_usage() + get_peak_memory_usage().

je donnerais avec défi Feu Noir un essai.

Il y a cette virtualBox que j'ai créée en utilisant marionnette, pour tester différents frameworks php fournis avec BlackFire, n'hésitez pas à créer et/ou distribuer si nécessaire :)

https://github.com/webit4me/PHPFrameworks

Pour l'analyse comparative, comme dans votre exemple, j'utilise le poire Benchmark emballer.Vous définissez des marqueurs pour mesurer.Le cours fournit également quelques aides à la présentation, ou vous pouvez traiter les données comme bon vous semble.

En fait, je l'ai enveloppé dans une autre classe avec une méthode __destruct.Lorsqu'un script se termine, la sortie est enregistrée via log4php dans syslog, j'ai donc beaucoup de données de performances sur lesquelles travailler.

XDebug n'est pas stable et n'est pas toujours disponible pour une version particulière de PHP.Par exemple, sur certains serveurs, j'utilise toujours php-5.1.6, - c'est ce qui est fourni avec RedHat RHEL5 (et d'ailleurs, il reçoit toujours des mises à jour pour tous les problèmes importants), et XDebug récent ne compile même pas avec ce php.J'ai donc fini par passer à Débogueur DBGC'est analyse comparative PHP fournit le timing des fonctions, des méthodes, des modules et même des lignes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top