Contenido

Acelerar el código Python con Pyjion

El compilador Pyjion de Microsoft para Python alcanza la versión estable 1.0

Qué es Pyjion

La forma más común de acelerar tu código Python es utilizar CPython, el intérprete oficial de Python. Este compila el código en un lenguaje intermedio llamado bytecode y evalúa este código cada vez que se ejecuta tu código. Esto permite mucha flexibilidad, pero tiene un inconveniente. Los cálculos sencillos en los que las CPUs son muy eficientes, como la aritmética de números enteros y de coma flotante, son significativamente más lentos en CPython que en otros intérpretes.

En la práctica, los desarrolladores de Python adoptan herramientas como Cython para hacer más eficientes las operaciones numéricas compilando el código por adelantado, utilizando extensiones de C. Esta es una solución eficaz para el rendimiento, pero no es ideal para la iteración rápida o la experimentación, especialmente en los cuadernos Jupyter.

Aquí es donde Pyjion viene a ayudar. Pyjion es un paquete de Python 3.10 que analiza el código de Python y lo optimiza sobre la marcha, utilizando un compilador JIT, o “Just-in-Time”. Se puede utilizar en un programa simplemente importando la biblioteca Pyjion y habilitándola. Todo lo que se ejecuta después de esa declaración se compila en JIT.

Cómo se pronuncia

“Pyjion” se pronuncia como la palabra “paloma”. @DinoV quería un nombre que tuviera algo con “Python” – la parte “Py” – y algo con “JIT” – la parte “JI” – y que fuera pronunciable.

Características principales

  • Compilador JIT guiado por perfiles
  • Soporte nativo de enteros y flotadores de 64 bits
  • Compilador pequeño y rápido
  • Windows, macOS y Linux
  • Compatible con CPUs Intel y ARM
  • Desensamblador IL y ASM incorporado
  • Soporte para herramientas nativas de depuración y perfilado

Tecnología

Pyjion compila el bytecode nativo de CPython en código máquina. Sin Pyjion, CPython utiliza un bucle de evaluación principal (llamado bucle de evaluación de cuadros) para iterar sobre los opcodes. El compilador Pyjion tiene 3 etapas principales:

  • Construir una “tabla de pila” de los tipos abstractos en cada posición de opcode
  • Compilar los opcodes de CPython en instrucciones IL (ECMA335 CIL)
  • Emitir los opcodes CIL en el compilador de .NET EE para convertirlos en código máquina/ensamblaje nativo

Puntos de referencia

Los benchmarks realizados por los mantenedores del proyecto muestran que Pyjion es alrededor de dos o tres veces más rápido que el Python normal para el trabajo en el mundo real.

Pyjion Benchmarks
Python 3.10 vs Python 3.10 + Pyjion

Algunas de las optimizaciones permiten aumentar la velocidad hasta 10 veces. La aritmética regular, que siempre es una buena candidata para ser optimizada en JIT, puede ser un orden de magnitud más rápida.

Limitaciones

Algunas características de Python, como las sentencias with o las sentencias async..await están aún no implementadas. Ambas están en la hoja de ruta. Pyjion incluye una capa de middleware que permite que las aplicaciones WSGI se ejecuten en Pyjion. Las aplicaciones de larga duración, como las aplicaciones web, son buenas candidatas para la aceleración JIT.

Instalación

Pyjion requiere:

Después de seguir los pasos de instalación, Pyjion es sólo un módulo de Python que puedes importar a tu entorno de Python:

1
python -m pip install pyjion

Después de importar Pyjion, active el JIT usando la función enable:

1
2
import pyjion
pyjion.enable()

Cualquier código Python que escribas o importes después de activar Pyjion será compilado en JIT. No necesitas ejecutar funciones en ninguna API especial, es completamente transparente:

1
2
3
4
>>> def half(x):
...    return x/2
>>> half(2)
1.0

También puedes ejecutar Pyjion contra cualquier script o módulo:

1
pyjion my_script.py

O, para un módulo existente de Python:

1
pyjion -m calendar

¡Eso es!

Comparación

Cómo se compara Pyjion con:

PyPy

PyPy es una implementación de Python con su propio JIT. La mayor diferencia en comparación con Pyjion es que PyPy no soporta todos los módulos de extensión de C sin modificación, a menos que usen CFFI o trabajen con el subconjunto selecto de la API de C de CPython que PyPy sí soporta. Pyjion también pretende soportar muchos compiladores JIT mientras que PyPy sólo soporta su compilador JIT personalizado.

Pyston

Pyston es una implementación de Python que utiliza LLVM como compilador JIT. Comparado con Pyjion, Pyston tiene soporte parcial de la API de CPython C pero no soporte completo. Pyston también sólo soporta LLVM como compilador JIT.

Numba

Numba es un compilador JIT para “código Python orientado a arrays y con mucha carga matemática”. Esto significa que Numba se centra en la computación científica mientras que Pyjion intenta optimizar todo el código Python. Numba también sólo soporta LLVM.

IronPython

IronPython es una implementación de Python que se implementa utilizando .NET. Aunque IronPython intenta ser utilizable desde .NET, Pyjion no tiene una historia de compatibilidad con .NET. Esto también significa que IronPython no puede usar módulos de extensión C mientras que Pyjion sí.

Nuitka, Shedskin

Tanto Nuitka como Shedskin son transpiladores de Python a C++, lo que significa que traducen el código Python a un código C++ equivalente. Al ser un JIT, Pyjion no es un transpilador.

Enlaces de interés