Sur les versions antérieures à python 3.5 l'interpréteur nous donnait la possibilité de générer du binaire optimisé dans un fichier spécifique pyo.
L'interpréteur python (par défaut CPython) peut recevoir une option :
- -O pour générer un fichier optimisé
- -OO la même chose que -O mais en enlevant les valeurs de __doc__
On peut également enregistrer cette valeur dans une variable d'environnement
- PYTHONOPTIMIZE=0 (pas d'option)
- PYTHONOPTIMIZE=1 est équivalent à -O
- PYTHONOPTIMIZE=2 est équivalent à -OO
Pour forcer la génération du bytecode il suffit d'appeler le module compileall qui est une librairie standard. Et vous voyez la génération des fichiers optimisés dans le dossier __cache__
$ ls -l __pycache__/
-rw-r--r-- 1 david david 119 juil. 25 12:34 file.cpython-310.opt-1.pyc
Dans le nom du fichier optimisé on retrouve
- le fichier : file
- l'interpréteur : CPython
- la version du python : 3.10
- l'option d'optimisation : opt-1 ou opt-2
- l'extension : pyc (car en python >=3.5 le pyo n'est pas utilisé, l'optimisation est comprise dans le pyc)
Lorsque cette option est activée, par exemple il n'est pas possible d'utiliser pdb car __debug__ vaudra False
Un autre point à connaître est la suppression des
assert
lorsque le flag est utilisé
Voici le cas d'exemple
Copier le code
1 2 3 4 5 6 7 8 9 10 11 12 # file.py print('hello') assert False # Interpreter $ export PYTHONOPTIMIZE=0 $ python3 file.py hello Traceback (most recent call last): File "/home/david/Downloads/test/file.py", line 2, in <module> assert False AssertionError
Et celui avec l'optimisation
Copier le code
1 2 3 4 5 6 7 8 9 10 # file.py print('hello') assert False # Interpreter $ export PYTHONOPTIMIZE=2 $ python3 -m compileall file.py Compiling 'file.py'... $ python3 file.py hello
Il est important de préciser que de passer par un pyo ou même pyc ne rend pas le programme plus rapide, mais le charge plus rapidement en mémoire
Copier le code
1 2 3 4 5 6 7 8 9 10 import timeit result = timeit.timeit("print('hello')", number=100000) print(result) # python file.py without flag -OO # 0.888337237000087 # python file.py without flag -OO # 0.9634458870023082
Sur les dernières versions de python il n'est pas recommandé d'utiliser cette option : PEP 488