Question Comment pouvez-vous profiler un script?


Le projet Euler et d'autres concours de codage ont souvent un délai d'exécution maximal ou les gens se vantent de la rapidité avec laquelle leur solution s'exécute. Avec python, parfois les approches sont quelque peu kludgey - c'est-à-dire, en ajoutant du code de synchronisation à __main__.

Quel est un bon moyen de profiler la durée d'exécution d'un programme python?


973
2018-02-24 16:01


origine


Réponses:


Python inclut un profileur appelé cProfil. Il donne non seulement le temps total de fonctionnement, mais aussi les heures de chaque fonction séparément, et vous indique combien de fois chaque fonction a été appelée, ce qui permet de déterminer facilement où vous devriez faire des optimisations.

Vous pouvez l'appeler depuis votre code ou depuis l'interpréteur, comme ceci:

import cProfile
cProfile.run('foo()')

Encore plus utile, vous pouvez appeler le profil cProfile lors de l'exécution d'un script:

python -m cProfile myscript.py

Pour le rendre encore plus facile, j'ai fait un petit fichier batch appelé 'profile.bat':

python -m cProfile %1

Donc tout ce que j'ai à faire est de courir:

profile euler048.py

Et je reçois ceci:

1007 function calls in 0.061 CPU seconds

Ordered by: standard name
ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.000    0.000    0.061    0.061 <string>:1(<module>)
 1000    0.051    0.000    0.051    0.000 euler048.py:2(<lambda>)
    1    0.005    0.005    0.061    0.061 euler048.py:2(<module>)
    1    0.000    0.000    0.061    0.061 {execfile}
    1    0.002    0.002    0.053    0.053 {map}
    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler objects}
    1    0.000    0.000    0.000    0.000 {range}
    1    0.003    0.003    0.003    0.003 {sum}

EDIT: Mise à jour du lien vers une bonne ressource vidéo de PyCon 2013 intitulée Profilage Python
Aussi via YouTube.


1073
2018-02-24 16:01



Il y a quelque temps j'ai fait pycallgraph qui génère une visualisation à partir de votre code Python. Modifier: J'ai mis à jour l'exemple pour travailler avec la dernière version.

Après un pip install pycallgraph et l'installation GraphViz vous pouvez l'exécuter depuis la ligne de commande:

pycallgraph graphviz -- ./mypythonscript.py

Ou, vous pouvez profiler des parties particulières de votre code:

from pycallgraph import PyCallGraph
from pycallgraph.output import GraphvizOutput

with PyCallGraph(output=GraphvizOutput()):
    code_to_profile()

L'un ou l'autre va générer un pycallgraph.png fichier similaire à l'image ci-dessous:

enter image description here


349
2017-08-06 05:37



Il est important de souligner que l'utilisation du profileur ne fonctionne (par défaut) que sur le thread principal, et que vous n'obtiendrez aucune information d'autres threads si vous les utilisez. Cela peut être un peu un gotcha car il est complètement non mentionné dans le documentation du profileur.

Si vous voulez également créer un fil de discussion, vous devez regarder le threading.setprofile() fonction dans les docs.

Vous pouvez également créer votre propre threading.Thread sous-classe pour le faire:

class ProfiledThread(threading.Thread):
    # Overrides threading.Thread.run()
    def run(self):
        profiler = cProfile.Profile()
        try:
            return profiler.runcall(threading.Thread.run, self)
        finally:
            profiler.dump_stats('myprofile-%d.profile' % (self.ident,))

et utilise ça ProfiledThread classe au lieu de la norme. Cela peut vous donner plus de flexibilité, mais je ne suis pas sûr que cela en vaille la peine, surtout si vous utilisez du code tiers qui n'utiliserait pas votre classe.


167
2017-12-17 16:30



Le wiki Python est une excellente page pour les ressources de profilage: http://wiki.python.org/moin/PythonSpeed/PerformanceTips#Profiling_Code

comme le sont les docs python: http://docs.python.org/library/profile.html

comme le montre Chris Lawlor cProfile est un excellent outil et peut facilement être utilisé pour imprimer à l'écran:

python -m cProfile -s time mine.py <args>

ou pour déposer:

python -m cProfile -o output.file mine.py <args>

PS> Si vous utilisez Ubuntu, assurez-vous d'installer python-profile

sudo apt-get install python-profiler 

Si vous produisez en fichier, vous pouvez obtenir de belles visualisations en utilisant les outils suivants

PyCallGraph: un outil pour créer des images de graphique d'appel
  installer:

 sudo pip install pycallgraph

courir:

 pycallgraph mine.py args

vue:

 gimp pycallgraph.png

Vous pouvez utiliser ce que vous voulez pour voir le fichier png, j'ai utilisé gimp
Malheureusement, je reçois souvent

dot: le graphique est trop grand pour les bitmaps cairo-renderer. Mise à l'échelle de 0.257079 pour s'adapter

ce qui rend mes images inutilement petites. Donc, je crée généralement des fichiers svg:

pycallgraph -f svg -o pycallgraph.svg mine.py <args>

PS> assurez-vous d'installer graphviz (qui fournit le programme de points):

sudo pip install graphviz

Graphiques alternatifs utilisant gprof2dot via @maxy / @quodlibetor:

sudo pip install gprof2dot
python -m cProfile -o profile.pstats mine.py
gprof2dot -f pstats profile.pstats | dot -Tsvg -o mine.svg

126
2017-10-08 00:04



Commentaire de Maxy sur cette réponse m'a assez aidé pour que je pense qu'il mérite sa propre réponse: j'avais déjà des fichiers .pstats générés par cProfile et je ne voulais pas relancer les choses avec pycallgraph, donc j'ai utilisé gprof2dot, et j'ai de jolis svgs:

$ sudo apt-get install graphviz
$ git clone https://github.com/jrfonseca/gprof2dot
$ ln -s "$PWD"/gprof2dot/gprof2dot.py ~/bin
$ cd $PROJECT_DIR
$ gprof2dot.py -f pstats profile.pstats | dot -Tsvg -o callgraph.svg

et BLAM!

Il utilise le point (la même chose que pycallgraph utilise) donc la sortie semble similaire. J'ai l'impression que gprof2dot perd moins d'informations cependant:

gprof2dot example output


113
2017-12-11 23:16



J'ai couru dans un outil pratique appelé SnakeViz lors de la recherche sur ce sujet. SnakeViz est un outil de visualisation de profilage basé sur le Web. Il est très facile à installer et à utiliser. La façon habituelle que je l'utilise est de générer un fichier de statistiques avec %prun et ensuite faire l'analyse dans SnakeViz.

La technique principale de Viz utilisée est Diagramme de Sunburst comme indiqué ci-dessous, dans lequel la hiérarchie des appels de fonctions est agencée sous la forme de couches d'arcs et d'informations temporelles codées dans leurs largeurs angulaires.

La meilleure chose est que vous pouvez interagir avec le tableau. Par exemple, pour zoomer, on peut cliquer sur un arc, et l'arc et ses descendants seront agrandis comme un nouveau rayon de soleil pour afficher plus de détails.

enter image description here


41
2018-05-25 08:06



Il convient également de mentionner le visualiseur de vidage cProfile GUI RunSnakeRun. Il vous permet de trier et sélectionner, zoomant sur les parties pertinentes du programme. Les tailles des rectangles dans l'image sont proportionnelles au temps pris. Si vous passez la souris sur un rectangle, il met en évidence cet appel dans la table et partout sur la carte. Lorsque vous double-cliquez sur un rectangle, il zoome sur cette partie. Il vous montrera qui appelle cette partie et ce que cette partie appelle.

L'information descriptive est très utile. Il vous montre le code de ce bit qui peut être utile lorsque vous traitez des appels de bibliothèque intégrés. Il vous indique quel fichier et quelle ligne pour trouver le code.

Je tiens également à souligner que le PO a dit «profilage» mais il semble qu'il voulait dire «timing». Gardez à l'esprit que les programmes seront plus lents lorsqu'ils seront profilés.

enter image description here


33
2018-02-22 16:18