3.4 KiB
Peephole optimization
Introduction
Lorsque du code python est exécuté, celui-ci est compilé en bytecode et enregistré dans des fichiers .pyc stockés dans
les répertoires __pycache__
. Ces fichiers .pyc contiennent une version optimisée et plus rapide du code.
L'objet code
L'objet compilé code:
- Est accessible depuis l'attribut
__code__
des fonctions, -
Contient le bytecode et d'autres informations nécessaires à CPython pour son exécution, notamment :
co_consts
: un tuple regroupant les constantes présentes dans la fonction,co_varnames
: un tuple regroupant le nom des variables locales utilisées par la fonction,co_names
: un tuple regroupant les noms non-locaux référencés dans le corps de la fonction.
L'optimisation Peephole
Durant la phase de transcription en bytecode, certaines données telles que les expressions numériques, strings et tuples sont optimisées et stockées dans des instruction bytecode.
Les expressions constantes
Les calculs numériques
Les expressions constantes telles que a = 30 * 8 * 70
sont optimisées.
Les chaines de caractères et tuples
Les strings dont la longueur <= 4096 et les tuples dont la longueur <= 256 sont optimisées, les autres, non.
Les membership tests
Les membership tests (opérateur in
et not in
) permettent de tester la présence d'une valeur dans des
sequences. Durant la phase de transcription, Python convertit les objets mutables (list et set) en leur version non mutables:
- Les lists en tuples,
- Les sets en frozen sets
def toto():
a = 30 * 8 * 7
b = "TDS" * 3
c = "T" * 4097
d = (1, 2) * 5
e = (10, ) * 257
f = [101, 102] * 2
print("Hello TDS !!!")
print(f'toto function constants: {toto.__code__.co_consts}')
print(f'toto fonction local variable names: {toto.__code__.co_varnames}')
print(f'toto fonction non-local names: {toto.__code__.co_names}')
toto function constants: (None, 1680, 'TDSTDSTDS', 'T', 4097, (1, 2, 1, 2, 1, 2, 1, 2, 1, 2), (10,), 257, 101, 102, 2, 'Hello TDS !!!') toto fonction local variable names: ('a', 'b', 'c', 'd', 'e', 'f') toto fonction non-local names: ('print',)
Commentaires :
30 * 8 * 70
est une expression constante et a été évaluée à16800
par le compilateur,“TDS” * 3
est aussi une expression constante et sa longueur est <= 4096. Elle a été évaluée àTDSTDSTDS
par le compilateur,“T” * 4097
, de longueur > 4096, n'est pas optimisée,(1, 2) * 5
est une séquence dont la longueur est <= 256 (10). Elle a été évaluée et stockée comme le tuple(1,2,1,2,1,2,1,2,1,2)
.(10,) * 257
de longueur > 256, n'est pas optimisée,[101, 102] * 2
est une list (objet mutable) et n'a pas été optimisée.
def toto():
for a in [10, 20, 30]:
pass
def titi():
for a in {40, 50, 60}:
pass
print(f'toto function constants: {toto.__code__.co_consts}')
print(f'titi function constants: {titi.__code__.co_consts}')
toto function constants: (None, (10, 20, 30)) titi function constants: (None, frozenset({40, 50, 60}))