Il existe plusieurs types de profilages.
* via ''cProfile'' : le temps d'exécution et le nombre d'exécutions de chaque fonction,
* via ''line_profiler'' : le temps d'exécution et le nombre d'exécutions de chaque ligne de chaque fonction annotée.
====cProfile====
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.
====line_profiler====
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.