Detalles internos de rendimiento de Python y exabruptos sobre asyncio https://podcast.jcea.es/python/14
Participantes:
Jesús Cea, email: jcea@jcea.es, twitter:
@jcea, https://blog.jcea.es/,
https://www.jcea.es/. Conectando desde Madrid.
Eduardo Castro, email:
info@ecdesign.es. Conectando desde A
Guarda.
Javier, conectando desde Madrid.
Víctor Ramírez, twitter: @virako,
programador python y amante de vim, conectando desde Huelva.
Juan Carlos, conectando desde Bilbao.
Audio editado por Pablo Gómez, twitter:
@julebek.
La música de la entrada y la salida es "Lightning Bugs", de Jason
Shaw. Publicada en https://audionautix.com/ con licencia
- Creative Commons Attribution 4.0 International
License.
A Pythonic technique you must know
Don’t Use Recursion In Python Any More,Python Closure — A
Pythonic technique you must know:
https://towardsdatascience.com/dont-use-recursion-in-python-any-more-918aad95094c.
Hilo en la lista de correo de Python Madrid:
https://lists.es.python.org/pipermail/madrid/2021-January/004838.html.
Closure:
https://es.wikipedia.org/wiki/Clausura_(inform%C3%A1tica).
Twisted daña el cerebro: https://twistedmatrix.com/trac/.
Black: https://pypi.org/project/black/.
from __future__ import braces.
' o ".
Cuando tienes if ... else ..., ¿Qué caso pones primero?,
¿el corto o el largo? ¿Primero la condición normal?
Microoptimizaciones que complican la legibilidad sin
ganancia de rendimiento que importe en realidad.
variable no impacta en el rendimiento.
https://es.wikipedia.org/wiki/Bytecode que genera Python.
Dispositivo de Duff:
https://es.wikipedia.org/wiki/Dispositivo_de_Duff.
El "bytecode" https://es.wikipedia.org/wiki/Bytecode que
genera Python no está nada optimizado. Es mejorable.
a + a:
>>> dis.dis(lambda a: a + a)
1 0 LOAD_FAST 0 (a)
2 LOAD_FAST 0 (a)
4 BINARY_ADD
6 RETURN_VALUE
¡Guardas!
Sí se hacen algunas optimizaciones simples:
>>> dis.dis(lambda : 5 + 3)
1 0 LOAD_CONST 1 (8)
2 RETURN_VALUE
calcular una expresión.
Máquina virtual de registros en vez de máquina virtual
orientada a pila.
Muchas operaciones redundantes:
>>> import dis
>>> def suma(valores):
... s=0
... for i in valores:
... s+=i
... return s
...
>>> dis.dis(suma)
2 0 LOAD_CONST 1 (0)
2 STORE_FAST 1 (s)3 4 LOAD_FAST 0 (valores)
6 GET_ITER
>> 8 FOR_ITER 12 (to 22)
10 STORE_FAST 2 (i)
4 12 LOAD_FAST 1 (s)
14 LOAD_FAST 2 (i)
16 INPLACE_ADD
18 STORE_FAST 1 (s)
20 JUMP_ABSOLUTE 8
5 >> 22 LOAD_FAST 1 (s)
24 RETURN_VALUE
¿Qué ocurre a la hora de depurar o para gestionar
excepciones?
¡Guardas!
NOTA DESDE EL FUTURO:
Python 3.9.5:
https://docs.python.org/release/3.9.5/whatsnew/changelog.html.
Traceback objects allow accessing frame objects without
triggering audit hooks:
https://bugs.python.org/issue42800.
Python son aburridas, pero no...
La complejidad debe estar en tu programa, no en el lenguaje
o el intérprete.
Compiladores optimizadores. Python se está quedando atrás.
Hacer caché al buscar atributos:
Issue1616125: Cached globals+builtins lookup optimization:
https://bugs.python.org/issue1616125.
issue43452: Microoptimize PyType_Lookup for cache hits
https://bugs.python.org/issue43452.
Detectar cambios en un diccionario, incluyendo
diccionarios internos como locals o __builtins__:
PEP 509 Add a private version to dict:
https://www.python.org/dev/peps/pep-0509/.
from __future__ import braces.
import antigravity.
import this.
import __hello__.
pass o ... (ellipsis).
Es algo interno para el API de C. No está accesible desde
Python.
Cambios pequeños pueden abrir posibilidades interesantes.
¡Guardas!.
traceback.clear_frames(tb):
https://docs.python.org/3/library/traceback.html#traceback.clear_frames.
Manipular frame.back.
Que una función sepa si se le está llamando de una forma
síncrona o asíncrona.
la programación asíncrona tal y como está implementada en Python.
Una biblioteca debe decidir si es síncrona o asíncrona y
"contamina" todo tu código.
Hacer corrutinas "de verdad":
https://es.wikipedia.org/wiki/Corrutina.
Persistencia y programación asíncrona.
Concepto de "awaitable":
https://docs.python.org/3/library/asyncio-task.html#awaitables.
future.result():
https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Future.result.
preparación formal de la charla o sin avisar con tiempo para
que la gente se lo pueda ver con calma antes.
https://docs.python.org/3/library/asyncio.html.
Vuelve a tratarse el tema de si la biblioteca estándar debe
crecer o adelgazar.
Según Jesús Cea, asyncio
https://docs.python.org/3/library/asyncio.html es la peor
opción.
Alternativas a asyncio:
Trio: https://trio.readthedocs.io/en/stable/.
Monkey patching:
https://en.wikipedia.org/wiki/Monkey_patch.
La dificultad de luchar con una biblioteca que está incluída
en la biblioteca estándar.
cosas además de para gestionar peticiones de la red.
concurrent.futures
https://docs.python.org/3/library/concurrent.futures.html que
threading https://docs.python.org/3/library/threading.html
directamente.
Transportar excepciones entre hilos.
Control de carga y paralelismo.
anterior: Issue35930: Raising an exception raised in a "future"
instance will create reference cycles
https://bugs.python.org/issue35930.
Queda por ultimar el detalle de cómo solucionar el problema
exactamente y enviar el parche para que se integre
oficialmente en Python.
Jesús Cea describe las dos opciones que está barajando:
weakrefs https://docs.python.org/3/library/weakref.html o
try ... finally.
introdujo el operador ternario en Python.