J'ai vu pas mal de questions sur le Projet Euler et d'autres endroits demandent combien de temps à l'exécution de leurs solutions. Parfois, les réponses données sont un peu kludgey - à-d., l'ajout de code de timing d' __main__
, j'ai donc pensé que je devais partager ma solution.
Réponses
Trop de publicités?Python comprend un générateur de profils appelé cProfile. Il donne non seulement du temps total d'exécution, mais aussi les temps de chaque fonction séparément, et vous indique le nombre de fois que chaque fonction a été appelée, le rendant facile à déterminer où vous devriez faire des optimisations.
Vous pouvez appeler à partir de votre code, ou de l'interprète, comme ceci:
import cProfile
cProfile.run('foo()')
Encore plus utile, vous pouvez appeler la 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é " profil.bat':
python -m cProfile %1
Donc, tout ce que j'ai à faire est de lancer:
profile euler048.py
Et j'obtiens 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}
MODIFIER Il y a un grand discours sur le profilage de PyCon ici: http://blip.tv/file/1957086
Il y a un moment j'ai fait pycallgraph
qui génère une visualisation à partir de votre code Python. Edit: j'ai mis à jour l'exemple de travailler avec la dernière version.
Après un pip install pycallgraph
, vous pouvez l'exécuter à partir de la ligne de commande:
pycallgraph graphviz -- ./mypythonscript.py
Ou, vous pouvez le profil particulier des parties de votre code:
from pycallgraph import PyCallGraph
from pycallgraph.output import GraphvizOutput
with PyCallGraph(output=GraphvizOutput()):
code_to_profile()
L'un de ces va générer un pycallgraph.png
fiche similaire à l'image ci-dessous:
Il est intéressant de souligner que l'utilisation du profileur fonctionne uniquement (par défaut) sur le thread principal, et vous ne serez pas obtenir toutes les informations à partir d'autres threads, si vous les utilisez. Cela peut être un peu un piège car il est complètement passé sous silence dans le profiler de la documentation.
Si vous aussi vous voulez le profil de threads, vous aurez envie de regarder à l' 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 l'utilisation que l' ProfiledThread
de la classe au lieu de la norme. Il peut vous donner plus de flexibilité, mais je ne suis pas sûr que ça vaut le coup, surtout si vous utilisez de la troisième partie du code qui ne serait pas utiliser votre classe.
Le python wiki est une grande page pour le profilage des ressources: http://wiki.python.org/moin/PythonSpeed/PerformanceTips#Profiling_Code
comme c'est le python docs: http://docs.python.org/library/profile.html
comme illustré par Chris Lawlor cProfile est un outil formidable, et peut facilement être utilisé pour imprimer à l'écran:
python -m cProfile -s time mine.py <args>
ou à déposer:
python -m cProfile -o output.file mine.py <args>
PS> Si vous utilisez Ubuntu, assurez-vous d'installer python-profil
sudo apt-get install python-profiler
Si vous la sortie vers un fichier, vous pouvez obtenir de belles visualisations en utilisant les outils suivants
PyCallGraph : un outil pour créer le graphe d'appel des images
installer:
sudo pip install pycallgraph
exécuter:
pycallgraph mine.py args
vue:
gimp pycallgraph.png
Vous pouvez utiliser ce que vous voulez pour afficher le fichier png, j'ai utilisé gimp
Malheureusement, je reçois souvent des
dot: le graphique est trop grand pour le caire-rendu d'images bitmap. Mise à l'échelle par 0.257079 pour s'adapter à
ce qui rend mes images unusably petit. J'ai donc en général de créer des fichiers svg:
pycallgraph -f svg -o pycallgraph.svg mine.py <args>
PS> Si vous utilisez Ubuntu, assurez-vous d'installer graphviz (qui fournit le point de programme):
sudo apt-get install graphviz
La variante de tracé de Graphiques à l'aide de gprof2dot via @maxy / @quodlibetor :
sudo apt-get install gprof2dot
python -m cProfile -o profile.pstats mine.py
gprof2dot -f pstats profile.pstats | dot -Tsvg -o mine.svg
@Maxy commentaire de cette réponse m'a aidé il suffit que je pense qu'il mérite sa propre réponse: j'ai déjà eu cProfile généré .pstats fichiers et je n'ai pas envie de refaire des choses avec pycallgraph, j'ai donc utilisé gprof2dot, et a eu assez svgs:
$ sudo apt-get install graphviz
$ git clone https://code.google.com/p/jrfonseca.gprof2dot/ 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 sortie ressemble. J'ai l'impression que gprof2dot perd moins d'informations si: