Il existe plusieurs types de profilages.
cProfile
: le temps d'exécution et le nombre d'exécutions de chaque fonction,line_profiler
: le temps d'exécution et le nombre d'exécutions de chaque ligne de chaque fonction annotée.
Il suffit d'exécuter le module python (-m module
) ou le fichier python (file.py
) depuis le module cProfile
.
python -m cProfile -m module -s tottime
Rendu :
ncalls tottime percall cumtime percall filename:lineno(function) 5 44.579 8.916 44.579 8.916 {HoughLinesP} 74 2.162 0.029 2.162 0.029 {method 'acquire' of '_thread.lock' objects} 55242 1.684 0.000 1.684 0.000 compute.py:344(get_perpendicular_throught_point) 295 1.552 0.005 1.552 0.005 {bitwise_and} 13 0.756 0.058 3.245 0.250 cv2ext.py:1043(remove_perpendicular_multiples_points) 15 0.731 0.049 0.731 0.049 {erode} 224 0.729 0.003 0.729 0.003 {bitwise_not} 16 0.722 0.045 0.722 0.045 {dilate}
avec :
ncalls
: le nombre d'appels de la fonction,tottime
: le temps d'exécution de la fonction sans le temps des fonctions appelées depuis la fonction,percall
: tottime
/ ncalls
,cumtime
: le temps d'exécution de la fonction avec le temps des fonctions appelées depuis la fonction,percall
: cumtime
/ ncalls
.Généralement, c'est le temps sans les appels de fonctions enfants qui vont nous intéresser. Les fonctions lambda sont bien considérées à part.
Il s'agit d'un module externe :
pip install line_profiler
Puis ensuite, il faut ajouter manuellement un décorateur à chaque fonction que l'on souhaite analyser.
@profile def test_0001_png() -> None: …
Il n'y a pas besoin de rajouter un import
. Le script ne sera pas exécuté directement par python mais par un autre programme.
kernprof -l -v file.py
Rendu :
Wrote profile results to run_all.py.lprof Timer unit: 1e-07 s Total time: 5.57215 s File: .\page\unskew.py Function: find_rotation at line 112 Line # Hits Time Per Hit % Time Line Contents ============================================================== 112 @profile 113 def find_rotation( 114 image: np.ndarray, 115 parameters: UnskewPageParameters, 116 approximate_angle: Angle, 117 debug: DebugImage, 118 ) -> Angle: 119 2 206.0 103.0 0.0 debug.image(image, DebugImage.Level.DEBUG) 120 121 2 87.0 43.5 0.0 images_mask = page.find_images.find_images( 122 2 47.0 23.5 0.0 image, 123 2 131.0 65.5 0.0 parameters.find_images, 124 2 71.0 35.5 0.0 approximate_angle, 125 2 7877801.0 3938900.5 14.1 debug, 126 )
Le temps inclut évidemment les appels aux fonctions enfants.
Si la fonction n'est pas dans le module principal, il faut ajouter un @profile
à la fonction appelante dans le module principal.