Dans ce guide, nous allons explorer l’utilisation de la fonction timeit
, un outil puissant intégré au module timeit
de Python. Vous apprendrez à mesurer avec précision le temps d’exécution d’expressions et de fonctions Python simples.
L’analyse temporelle de votre code est essentielle pour évaluer l’efficacité de différentes sections et pour identifier les parties qui nécessitent une optimisation.
Nous débuterons par l’étude de la syntaxe de la fonction timeit
, puis nous passerons à des exemples pratiques pour comprendre comment l’appliquer à des portions de code et à des fonctions dans votre projet Python. Plongeons-nous dans le sujet.
Comment utiliser la fonction timeit
de Python
Le module timeit
est inclus dans la bibliothèque standard de Python. Pour l’utiliser, commencez par l’importer :
import timeit
La syntaxe générale d’utilisation de la fonction timeit
est la suivante :
timeit.timeit(stmt, setup, number)
Où :
stmt
est le fragment de code dont vous voulez mesurer le temps d’exécution. Il peut s’agir d’une simple chaîne, d’une chaîne multiligne ou du nom d’une fonction.setup
, comme son nom l’indique, est un code qui n’est exécuté qu’une seule fois, généralement pour mettre en place l’environnement nécessaire à l’exécution destmt
. Par exemple, pour mesurer la création d’un tableau NumPy, l’importation de NumPy ferait partie de la configuration.number
indique le nombre de fois questmt
sera exécuté. Sa valeur par défaut est un million (1000000), mais vous pouvez la modifier à votre convenance.
Maintenant que vous êtes familiarisé avec la syntaxe, passons à des exemples concrets.
Mesure du temps d’expressions Python basiques
Dans cette section, nous allons nous concentrer sur la mesure du temps d’exécution d’expressions Python élémentaires avec timeit
.
Ouvrez un interpréteur Python (REPL) et testez les exemples ci-dessous. Nous allons calculer le temps nécessaire pour effectuer des opérations d’exponentiation et de division euclidienne, en répétant l’exécution 10 000 et 100 000 fois.
Notez que l’instruction à évaluer est passée sous forme de chaîne de caractères, et que nous utilisons un point-virgule pour séparer les expressions.
>>> import timeit >>> timeit.timeit('3**4;3//4',number=10000) 0.0004020999999738706 >>> timeit.timeit('3**4;3//4',number=100000) 0.0013780000000451764
Utilisation de timeit
en ligne de commande
timeit
peut également être utilisé directement depuis la ligne de commande. Voici la syntaxe pour l’équivalent de l’appel de la fonction timeit
:
$ python -m timeit -n [nombre] -s [configuration] [instruction]
python -m timeit
indique que nous utilisonstimeit
comme module principal.-n
est l’option spécifiant le nombre d’exécutions du code, équivalente à l’argumentnumber
de la fonctiontimeit()
.- L’option
-s
permet de définir le code de configuration.
Reprenons l’exemple précédent en utilisant la version en ligne de commande :
$ python -m timeit -n 100000 '3**4;3//4' 100000 loops, best of 5: 35.8 nsec per loop
Dans cet exemple, nous mesurons le temps d’exécution de la fonction intégrée len()
. L’initialisation de la chaîne est le code de configuration, spécifié par l’option -s
.
$ python -m timeit -n 100000 -s "string_1 = 'coding'" 'len(string_1)' 100000 loops, best of 5: 239 nsec per loop
Notez que la sortie indique le meilleur temps parmi 5 exécutions. En effet, lorsque timeit
est utilisé en ligne de commande, l’option -r
est par défaut fixée à 5, ce qui signifie que l’exécution de l’instruction (stmt
) est répétée cinq fois et seul le meilleur temps est conservé.
Analyse de méthodes d’inversion de chaînes avec timeit
Lors de la manipulation de chaînes de caractères en Python, il est fréquent de devoir les inverser. Les deux techniques les plus courantes pour réaliser cette opération sont :
- L’utilisation du découpage de chaînes.
- L’emploi de la fonction
reversed()
combinée à la méthodejoin()
.
Inversion de chaînes via le découpage
Explorons le fonctionnement du découpage de chaînes et comment il peut être utilisé pour inverser une chaîne. L’expression une_chaîne[début:fin]
renvoie une partie de la chaîne, allant de l’index début
jusqu’à l’index fin-1
. Prenons un exemple.
Considérons la chaîne ‘Python’. Elle est de longueur 6, et les indices vont de 0 à 5.
>>> string_1 = 'Python'
Si vous spécifiez les indices de début et de fin, la partie de la chaîne extraite commencera à l’indice de début et se terminera juste avant l’indice de fin. Par exemple, string_1[1:4]
renvoie ‘yth’.
>>> string_1 = 'Python' >>> string_1[1:4] 'yth'
Si l’indice de début est omis, la tranche commencera à l’index 0 et s’étendra jusqu’à fin-1
.
Ici, l’indice de fin est 3, donc la tranche comprend les indices 0, 1 et 2.
>>> string_1[:3] 'Pyt'
Si l’indice de fin est omis, la tranche débutera à l’indice de début et s’étendra jusqu’à la fin de la chaîne.
>>> string_1[1:] 'ython'
Omettre les deux indices permet d’obtenir une copie complète de la chaîne.
>>> string_1[::] 'Python'
Il est également possible d’ajouter un pas. Par exemple, en définissant les valeurs de début, de fin et de pas à 1, 5 et 2 respectivement, on obtient une tranche commençant à 1, allant jusqu’à 4 (non inclus) en prenant un caractère sur deux.
>>> string_1[1:5:2] 'yh'
Un pas négatif permet de parcourir la chaîne en sens inverse. Par exemple, string_1[5:2:-2]
donne la tranche :
>>> string_1[5:2:-2] 'nh'
Pour inverser une chaîne, il suffit donc de ne pas spécifier d’indices de début et de fin et de définir le pas à -1 :
>>> string_1[::-1] 'nohtyP'
En résumé, chaîne[::-1]
renvoie une copie inversée de la chaîne.
Inversion de chaînes avec des fonctions intégrées et méthodes
La fonction intégrée reversed()
de Python retourne un itérateur qui parcourt la chaîne en sens inverse.
>>> string_1 = 'Python' >>> reversed(string_1) <reversed object at 0x00BEAF70>
Vous pouvez alors utiliser une boucle for
pour parcourir cet itérateur et accéder aux éléments de la chaîne dans l’ordre inverse.
for char in reversed(string_1): print(char)
Voici la sortie :
# Output n o h t y P
Ensuite, vous pouvez faire appel à la méthode join()
sur l’itérateur inverse, selon la syntaxe : <séparateur>.join(reversed(chaîne))
.
L’exemple ci-dessous montre des exemples où les séparateurs sont respectivement un tiret et un espace.
>>> '-'.join(reversed(string1)) 'n-o-h-t-y-P' >>> ' '.join(reversed(string1)) 'n o h t y P'
Dans notre cas, nous ne voulons aucun séparateur, donc nous définissons le séparateur à une chaîne vide pour obtenir une copie inversée de la chaîne :
>>> ''.join(reversed(string1)) 'nohtyP'
L’expression ''.join(reversed(chaîne))
renvoie ainsi une copie inversée de la chaîne.
Comparaison des temps d’exécution avec timeit
Nous avons maintenant deux méthodes pour inverser une chaîne. Mais laquelle est la plus rapide ? Vérifions-le.
Dans un exemple précédent, nous avons mesuré le temps d’expressions simples sans configurer de code spécifique. Ici, nous inversons des chaînes Python. L’opération d’inversion est répétée le nombre de fois spécifié par l’argument number
, tandis que le code de configuration, qui consiste à l’initialisation de la chaîne, n’est exécuté qu’une seule fois.
>>> import timeit >>> timeit.timeit(stmt="string_1[::-1]", setup = "string_1 = 'Python'", number = 100000) 0.04951830000001678 >>> timeit.timeit(stmt = "''.join(reversed(string_1))", setup = "string_1 = 'Python'", number = 100000) 0.12858760000000302
Pour le même nombre d’exécutions, l’approche par découpage est plus rapide que celle utilisant join()
et reversed()
.
Mesure du temps d’exécution de fonctions Python avec timeit
Dans cette section, nous allons apprendre à mesurer le temps d’exécution de fonctions Python avec timeit
. Prenons l’exemple d’une fonction nommée hasDigit
qui prend en argument une liste de chaînes et retourne la liste des chaînes contenant au moins un chiffre.
def hasDigit(somelist): str_with_digit = [] for string in somelist: check_char = [char.isdigit() for char in string] if any(check_char): str_with_digit.append(string) return str_with_digit
Nous souhaitons évaluer le temps d’exécution de cette fonction hasDigit()
à l’aide de timeit
.
Identifions d’abord l’instruction à évaluer (stmt
). Il s’agit de l’appel de la fonction hasDigit()
avec une liste de chaînes en argument. Ensuite, nous devons définir le code de configuration. Qu’est-ce qu’il devrait comprendre ?
Pour que l’appel de fonction fonctionne correctement, le code de configuration doit inclure :
- La définition de la fonction
hasDigit()
. - L’initialisation de la liste de chaînes à passer en argument.
Définissons le code de configuration sous forme de chaîne :
setup = """ def hasDigit(somelist): str_with_digit = [] for string in somelist: check_char = [char.isdigit() for char in string] if any(check_char): str_with_digit.append(string) return str_with_digit thislist=['puffin3','7frost','blue'] """
Maintenant, nous pouvons utiliser timeit
pour mesurer le temps d’exécution de hasDigit()
pour 100 000 exécutions.
import timeit timeit.timeit('hasDigit(thislist)',setup=setup,number=100000)
# Output 0.2810094920000097
Conclusion
Vous avez appris à utiliser la fonction timeit
de Python pour mesurer le temps d’expressions, de fonctions et d’autres objets appelables. Cet outil est précieux pour comparer différents algorithmes, évaluer l’impact de modifications de code et pour optimiser les performances de vos projets.
Récapitulons ce que nous avons vu dans ce tutoriel. La fonction timeit()
s’utilise avec la syntaxe timeit.timeit(stmt=...,setup=...,number=...)
. Alternativement, timeit
peut être utilisé en ligne de commande pour évaluer des portions de code courtes.
Pour aller plus loin, vous pouvez explorer d’autres outils de profilage Python, comme line-profiler
pour analyser le temps d’exécution ligne par ligne, et memprofiler
pour étudier l’utilisation de la mémoire.
Ensuite, vous pouvez apprendre à calculer le décalage horaire en Python.