Python 3.14 expone sys._jit, un pequeño conjunto de utilidades para observar el compilador JIT experimental de CPython. JIT significa just-in-time compilation: ciertas partes del código ejecutadas muchas veces pueden compilarse durante la ejecución. El objetivo es reducir parte del coste del intérprete en rutas “calientes”, pero no existe una garantía de aceleración para todos los programas.
La interfaz permite saber si el ejecutable admite JIT, si está habilitado en el proceso actual y si el frame superior parece ejecutar código compilado en un instante concreto. No ofrece una API estable para forzar la compilación, marcar funciones ni elegir optimizaciones.
Qué cambia el JIT de CPython
CPython normalmente ejecuta bytecode mediante su intérprete. El JIT experimental puede especializar y compilar algunas rutas frecuentes. El resultado depende del tipo de carga, del tiempo de calentamiento, del procesador, del sistema operativo, de la compilación usada y de detalles internos que pueden cambiar.
Un programa limitado por red, disco, bases de datos o bibliotecas nativas puede mostrar poca diferencia. Los bucles intensivos escritos principalmente en Python tienen más posibilidades de beneficiarse, aunque siempre hay que medir.
Comprobar si sys._jit existe
import sys
jit = getattr(sys, "_jit", None)
if jit is None:
print("Esta versión no expone sys._jit")
else:
print("sys._jit está disponible")
Usa getattr si necesitas compatibilidad con versiones anteriores u otras implementaciones. El guion bajo inicial indica que se trata de un detalle de implementación y no de una característica portátil del lenguaje.
sys._jit.is_available()
is_available() devuelve True cuando el ejecutable actual fue compilado con soporte para el JIT experimental. Esto describe una capacidad del binario, no el estado del proceso.
import sys
jit = getattr(sys, "_jit", None)
if jit and jit.is_available():
print("Este CPython admite JIT")
else:
print("JIT no disponible")
Esta comprobación es útil en informes de entorno, CI, diagnósticos y bancos de pruebas.
sys._jit.is_enabled()
is_enabled() indica si el JIT está habilitado en el proceso actual. Una compilación puede admitirlo y ejecutarse con la función desactivada. La configuración puede depender de PYTHON_JIT, definida antes de iniciar Python.
import sys
jit = getattr(sys, "_jit", None)
if jit is None:
estado = "no expuesto"
elif not jit.is_available():
estado = "binario sin JIT"
elif jit.is_enabled():
estado = "habilitado"
else:
estado = "admitido pero deshabilitado"
print(estado)
Registra esta información al publicar resultados, porque dos procesos con la misma versión pueden usar compilaciones diferentes.
sys._jit.is_active()
is_active() intenta informar si el frame Python superior ejecuta código JIT en ese momento. Está pensado principalmente para probar y depurar el propio compilador. No debería controlar la lógica de una aplicación.
import sys
jit = getattr(sys, "_jit", None)
if jit and jit.is_enabled():
print("Activo ahora:", jit.is_active())
El valor puede resultar sorprendente. La llamada de inspección o un if puede mover la ejecución hacia una ruta fría interpretada. Por eso, varias llamadas cercanas no tienen por qué devolver lo mismo.
No cambies la lógica según el JIT
# Evita este diseño
if getattr(sys, "_jit", None) and sys._jit.is_active():
resultado = algoritmo_a(datos)
else:
resultado = algoritmo_b(datos)
El programa debe producir resultados equivalentes con el JIT activado o desactivado. Elige algoritmos por tamaño de datos, precisión, memoria y mediciones, no por un estado transitorio.
Una función segura de diagnóstico
import sys
def obtener_estado_jit():
jit = getattr(sys, "_jit", None)
if jit is None:
return {
"expuesto": False,
"disponible": False,
"habilitado": False,
}
disponible = bool(jit.is_available())
habilitado = bool(jit.is_enabled()) if disponible else False
return {
"expuesto": True,
"disponible": disponible,
"habilitado": habilitado,
}
print(obtener_estado_jit())
Este patrón funciona bien para logs, soporte y metadatos de benchmarks, sin romper entornos incompatibles.
Cómo medir el rendimiento
Compara procesos separados: uno con JIT habilitado y otro deshabilitado. Incluye calentamiento antes de medir, ya que el runtime necesita detectar código caliente.
from time import perf_counter
def trabajo(repeticiones):
total = 0
for i in range(repeticiones):
total += (i * 3) % 97
return total
for _ in range(20):
trabajo(100_000)
inicio = perf_counter()
resultado = trabajo(5_000_000)
tiempo = perf_counter() - inicio
print(resultado, tiempo)
No incluyas importaciones, inicio del proceso o entrada y salida no relacionada. Repite varias veces, compara medianas y registra la variación.
Procesos separados y entorno reproducible
Las variables de inicio deben configurarse antes de lanzar Python. Guarda sys.version, sys.implementation, la plataforma y el estado JIT junto con cada medición.
Un microbenchmark breve puede no representar una aplicación real. Combina pruebas aisladas con escenarios completos y distingue CPU, red, disco y bibliotecas externas.
Compatibilidad y fallback
Una biblioteca pública no debería exigir sys._jit salvo que apunte específicamente a CPython experimental. Para telemetría opcional, devuelve un estado neutral.
def jit_habilitado():
import sys
jit = getattr(sys, "_jit", None)
return bool(jit and jit.is_available() and jit.is_enabled())
Utiliza el resultado para diagnóstico, no para corrección funcional.
Otras implementaciones
PyPy utiliza JIT desde hace años, pero no está obligado a exponer la misma interfaz. GraalPy, MicroPython y otras implementaciones poseen estrategias diferentes. Puedes registrar sys.implementation.name, pero evita llenar el proyecto de ramas específicas.
Pruebas con y sin JIT
Si una prueba falla solo con JIT, revisa supuestos temporales, estado global mutable, concurrencia, extensiones nativas y comportamiento indefinido. El resultado funcional debería mantenerse. En proyectos interesados en el experimento, añade un job de CI separado.
Observabilidad sin ruido
Registra disponibilidad y activación una vez al iniciar. Consultar is_active() continuamente no crea una métrica útil y puede influir en la ruta observada. Para localizar cuellos de botella, usa perfiles y benchmarks controlados.
Seguridad y despliegue
El JIT no es un sandbox y no hace seguro el código no confiable. Mantén validación de entradas, aislamiento, control de dependencias y pruebas de extensiones. En producción, fija versiones exactas y considera que una función experimental puede cambiar.
Cuándo puede ayudar
Las cargas con bucles Python prolongados y operaciones repetidas son candidatas razonables. Aplicaciones web que pasan la mayor parte del tiempo esperando servicios externos probablemente notarán menos impacto. Perfila antes de optimizar.
Errores comunes
No confundas “disponible” con “habilitado”. No uses is_active() como interruptor de algoritmos. No compares una ejecución fría con otra ya calentada. No publiques una cifra sin indicar compilación, versión, plataforma y método.
Contenido relacionado
Continúa con los artículos de Academify sobre timeit en Python, cProfile, por qué Python es lento y el GIL de Python. Consulta también la documentación oficial de sys y el repositorio de CPython.
Conclusión
sys._jit separa tres conceptos: soporte en el ejecutable, activación en el proceso y actividad momentánea de un frame. Para aplicaciones normales, is_available() e is_enabled() son datos de diagnóstico. Evita basar la lógica en is_active(). Protege el acceso con getattr, compara procesos independientes, incluye calentamiento, registra versiones y considera cualquier mejora como un resultado medido, no como una promesa.







