Weekly backup.

This commit is contained in:
2022-06-04 12:57:39 +02:00
parent e552583393
commit 015b896f65
68 changed files with 3530 additions and 27 deletions

View 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}))