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.