Profilage en Python: Qui a appelé la fonction?
Je suis profilage en Python à l'aide de cProfile
. J'ai trouvé une fonction qui prend beaucoup de temps CPU. Comment puis-je trouver la fonction qui est de l'appel de cette fonction lourde les la plupart?
EDIT:
Je vais régler pour une solution de contournement: puis-je écrire un Python de ligne à l'intérieur de cette lourde fonction qui imprime le nom de la fonction qui a appelé?
Vous devez vous connecter pour publier un commentaire.
Qui peuvent ne pas répondre directement à votre question, mais va certainement aider. Si l'utilisation du profiler avec l'option --tri cumulé il va trier les fonctions en temps cumulé. Ce qui est utile pour détecter non seulement lourde, de fonctions mais la de fonctions qui les appellent.
Il y a une solution pour obtenir de l'appelant la fonction:
Vous pouvez ajouter autant de f_back que vous le souhaitez dans le cas où vous voulez l'appelant de l'appelant, etc
Si vous souhaitez calculer les appels fréquents que vous pouvez faire ceci:
De les imprimer ensuite par ordre de fréquence:
pstats
module pour charger le profil, puis vous pouvez interroger directement la lourde fonction des appelants:loaded_stats_object.print_callers('heavy_function')
J'ai presque toujours afficher la sortie de la cProfile module à l'aide de Gprof2dot, fondamentalement, il convertit la sortie dans un graphvis graphique (une
.dot
fichier), par exemple:Il devient très facile de déterminer la fonction qui est la plus lente, et qui en fonction de[s] a appelée.
D'Usage:
inspecter.pile() vous donnera le courant de l'appelant de la pile.
Vous voudrez peut-être jeter un oeil à pycallgraph.
Il est possible de le faire à l'aide du générateur de profils
cProfile
dans la bibliothèque standard.Dans
pstats.Stats
(le profiler suite) il y a la méthodeprint_callees
(ou alternativementprint_callers
).Exemple de code:
Résultat sera quelque chose comme:
Sur la gauche vous avez l'appelant, sur la droite, vous avez le destinataire de l'appel.
(par exemple
_fixtext
été appelé à partir de_data
47827 temps et de_start_list
46429 fois)Voir aussi:
Couple de notes:
(c'est à dire pas possible de l'utiliser en ligne de commande comme
python -m cProfile myscript.py
. S'il est possible d'écrire un script séparé pour qu')strip_dirs()
doit aller de l'avantsort_stats()
(sinon le tri ne fonctionne pas)Je n'ai pas utilisé cProfile moi-même, mais la plupart des profileurs de vous donner un appel hiérarchie.
Une recherche sur google, j'ai trouvé ce les diapositives sur cProfile. Peut-être cela peut vous aider. Page 6 ressemble cProfile fournit une hiérarchie.
Désolé, je ne suis pas familier avec Python, mais il y a un méthode générale qui fonctionne, en supposant que vous pouvez manuellement interrompre l'exécution à un moment aléatoire.
Viens de le faire, et d'afficher la pile d'appel. Il vous dira, avec une forte probabilité, ce que vous voulez savoir. Si vous voulez être plus certain, il suffit de faire plusieurs fois.
Cela fonctionne parce que la culpabilité de l'appelant doit être sur la pile d'appel pour la fraction de temps qui est perdu, ce qui les expose à votre interrompt pour que la plupart du temps, si elle est répartie sur de nombreux appels courts ou un peu longues.
REMARQUE: Ce processus est plus comme le diagnostic de la mesure. Supposons que la mauvaise appel est perdre 90% du temps. Ensuite, chaque fois que vous l'arrêter, la probabilité de 90% que la mauvaise instruction d'appel est à droite sur la pile d'appel pour vous voir, et vous serez en mesure de voir que c'est mauvais. Toutefois, si vous voulez mesurer précisément le gaspillage, c'est un autre problème. Pour cela, vous aurez besoin de beaucoup plus d'échantillons, pour voir ce qu' % d'entre eux contiennent à cet appel. Ou sinon, juste corriger le coupable appel, l'horloge de l'accélération, et qui vous dira exactement ce que le gaspillage a été.
Pycscope fait cela. Je viens de le trouver aujourd'hui, donc je ne peux pas parler de la manière dont il est bon, mais les quelques exemples que j'ai essayé ont été très bon (mais pas parfaite).
https://pypi.python.org/pypi/pycscope/
Vous l'utiliser pour générer un cscope fichier, puis un cscope plugin à partir d'un éditeur VIM en particulier. J'ai essayé de l'utiliser avec de la vanille cscope, il semble que la plaine de cscope devient confus.