J'ai essayé d'utiliser le module line_profiler pour obtenir un profil ligne par ligne sur un fichier Python. C'est ce que j'ai fait jusqu'à présent:
1) Line_profiler installé à partir de pypi en utilisant le fichier .exe (je suis sur WinXP et Win7). Il suffit de cliquer sur l'assistant d'installation.
2) A écrit un petit morceau de code (semblable à ce qui a été demandé dans une autre question répondue ici ).
from line_profiler import LineProfiler
def do_stuff(numbers):
print numbers
numbers = 2
profile = LineProfiler(do_stuff(numbers))
profile.print_stats()
3) Exécutez le code depuis IDLE/PyScripter. Je n'ai que le temps.
Timer unit: 4.17188e-10 s
Comment obtenir un profil complet ligne par ligne sur le code que j'exécute? Je n'ai jamais utilisé de fonctionnalités avancées Python comme les décorateurs, il est donc difficile pour moi de comprendre comment utiliser les directives fournies par plusieurs articles comme ici et - ici .
Suivez simplement l'exemple de Dan Riti du premier link , mais utilisez votre code. Tout ce que vous avez à faire après avoir installé le line_profiler
le module est ajouter un @profile
décorateur juste avant chaque fonction que vous souhaitez profiler ligne par ligne et assurez-vous que chacune est appelée au moins une fois ailleurs dans le code — donc pour votre exemple de code trivial, ce serait quelque chose comme ceci:
example.py
fichier:
@profile
def do_stuff(numbers):
print numbers
numbers = 2
do_stuff(numbers)
Cela fait, exécutez votre script via le kernprof.py
✶ qui a été installé dans votre C:\Python27\Scripts
répertoire. Voici la sortie réelle (pas très intéressante) de cette opération dans une session de ligne de commande Windows 7:
> python "C:\Python27\Scripts\kernprof.py" -l -v example.py
2
Wrote profile results to example.py.lprof
Timer unit: 3.2079e-07 s
File: example.py
Function: do_stuff at line 2
Total time: 0.00185256 s
Line # Hits Time Per Hit % Time Line Contents
==============================================================
1 @profile
2 def do_stuff(numbers):
3 1 5775 5775.0 100.0 print numbers
Vous devrez probablement adapter cette dernière étape: l'exécution de votre script de test avec kernprof.py
au lieu de directement par l'interpréteur Python - afin de faire l'équivalent depuis IDLE ou PyScripter.
✶Mise à jour
Il semble que dans line_profiler
v1.0, l'utilitaire kernprof
est distribué en tant qu'exécutable, pas en .py
fichier de script tel qu'il était lorsque j'ai écrit ce qui précède. Cela signifie que les éléments suivants doivent maintenant être utilisés pour l'invoquer à partir de la ligne de commande:
> "C:\Python27\Scripts\kernprof.exe" -l -v example.py
Cette réponse est une copie de ma réponse ici pour savoir comment obtenir line_profiler
statistiques à partir d'un script Python (sans utiliser kernprof
depuis la ligne de commande ni avoir à ajouter @profile
décorateurs de fonctions et méthodes de classe). Toutes les réponses (que j'ai vues) à similaires line_profiler
les questions décrivent uniquement l'utilisation de kernprof
.
Le line_profiler
les cas de test (trouvés sur GitHub ) ont un exemple de génération de données de profil à partir d'un script Python. Vous devez encapsuler la fonction que vous voulez profil, puis appelez l'encapsuleur en passant les arguments de fonction souhaités.
from line_profiler import LineProfiler
import random
def do_stuff(numbers):
s = sum(numbers)
l = [numbers[i]/43 for i in range(len(numbers))]
m = ['hello'+str(numbers[i]) for i in range(len(numbers))]
numbers = [random.randint(1,100) for i in range(1000)]
lp = LineProfiler()
lp_wrapper = lp(do_stuff)
lp_wrapper(numbers)
lp.print_stats()
Production:
Timer unit: 1e-06 s
Total time: 0.000649 s
File: <ipython-input-2-2e060b054fea>
Function: do_stuff at line 4
Line # Hits Time Per Hit % Time Line Contents
==============================================================
4 def do_stuff(numbers):
5 1 10 10.0 1.5 s = sum(numbers)
6 1 186 186.0 28.7 l = [numbers[i]/43 for i in range(len(numbers))]
7 1 453 453.0 69.8 m = ['hello'+str(numbers[i]) for i in range(len(numbers))]
Ajout de fonctions supplémentaires au profil
Vous pouvez également ajouter des fonctions supplémentaires à profiler également. Par exemple, si vous aviez une deuxième fonction appelée et que vous enveloppez uniquement la fonction appelant, vous ne verrez que les résultats du profil de la fonction appel fonction.
from line_profiler import LineProfiler
import random
def do_other_stuff(numbers):
s = sum(numbers)
def do_stuff(numbers):
do_other_stuff(numbers)
l = [numbers[i]/43 for i in range(len(numbers))]
m = ['hello'+str(numbers[i]) for i in range(len(numbers))]
numbers = [random.randint(1,100) for i in range(1000)]
lp = LineProfiler()
lp_wrapper = lp(do_stuff)
lp_wrapper(numbers)
lp.print_stats()
Ce qui précède ne produirait que la sortie de profil suivante pour la fonction appel:
Timer unit: 1e-06 s
Total time: 0.000773 s
File: <ipython-input-3-ec0394d0a501>
Function: do_stuff at line 7
Line # Hits Time Per Hit % Time Line Contents
==============================================================
7 def do_stuff(numbers):
8 1 11 11.0 1.4 do_other_stuff(numbers)
9 1 236 236.0 30.5 l = [numbers[i]/43 for i in range(len(numbers))]
10 1 526 526.0 68.0 m = ['hello'+str(numbers[i]) for i in range(len(numbers))]
Dans ce cas, vous pouvez ajouter la fonction supplémentaire appelée au profil comme ceci:
from line_profiler import LineProfiler
import random
def do_other_stuff(numbers):
s = sum(numbers)
def do_stuff(numbers):
do_other_stuff(numbers)
l = [numbers[i]/43 for i in range(len(numbers))]
m = ['hello'+str(numbers[i]) for i in range(len(numbers))]
numbers = [random.randint(1,100) for i in range(1000)]
lp = LineProfiler()
lp.add_function(do_other_stuff) # add additional function to profile
lp_wrapper = lp(do_stuff)
lp_wrapper(numbers)
lp.print_stats()
Production:
Timer unit: 1e-06 s
Total time: 9e-06 s
File: <ipython-input-4-dae73707787c>
Function: do_other_stuff at line 4
Line # Hits Time Per Hit % Time Line Contents
==============================================================
4 def do_other_stuff(numbers):
5 1 9 9.0 100.0 s = sum(numbers)
Total time: 0.000694 s
File: <ipython-input-4-dae73707787c>
Function: do_stuff at line 7
Line # Hits Time Per Hit % Time Line Contents
==============================================================
7 def do_stuff(numbers):
8 1 12 12.0 1.7 do_other_stuff(numbers)
9 1 208 208.0 30.0 l = [numbers[i]/43 for i in range(len(numbers))]
10 1 474 474.0 68.3 m = ['hello'+str(numbers[i]) for i in range(len(numbers))]
REMARQUE: l'ajout de fonctions au profil de cette manière ne nécessite pas de modifications du code profilé (c'est-à-dire, pas besoin d'ajouter @profile
décorateurs).