Weekly backup.
This commit is contained in:
78
20220501130626-python_peephole_optimization.org
Normal file
78
20220501130626-python_peephole_optimization.org
Normal file
@@ -0,0 +1,78 @@
|
||||
:PROPERTIES:
|
||||
:ID: 26e1fdfb-1f8e-4c62-a08f-468a56ab03c8
|
||||
:mtime: 20220501153548
|
||||
:ctime: 20220501130626
|
||||
:END:
|
||||
#+title: 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*
|
||||
|
||||
#+BEGIN_SRC python :results output
|
||||
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}')
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
: 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.
|
||||
|
||||
#+BEGIN_SRC python :results output
|
||||
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}')
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
: toto function constants: (None, (10, 20, 30))
|
||||
: titi function constants: (None, frozenset({40, 50, 60}))
|
Reference in New Issue
Block a user