La compilazione "Just-in-Time" (JIT) è stata a lungo la chiave di volta per accelerare i linguaggi interpretati. Fino a poco tempo fa, in Python, questo significava affidarsi a librerie di terze parti come Numba o interpreti alternativi come PyPy. Con Python 3.15, ancora in fase Alpha ma già testabile, il team di sviluppo core ha integrato un JIT nativo che inizia a mostrare i muscoli.
I risultati preliminari indicano che il JIT nativo può accelerare l'esecuzione del codice fino al 20% o più, sebbene i guadagni dipendano drasticamente dal tipo di operazione. Mentre alcuni programmi mostrano miglioramenti drammatici, altri rimangono invariati. È il segnale che il lavoro di ottimizzazione sta iniziando a pagare dividendi.
Stato: Sperimentale
Il JIT è disabilitato di default. Per attivarlo è necessario impostare la variabile d'ambiente PYTHON_JIT=1. È sconsigliato abilitarlo globalmente nel proprio ambiente utente; meglio utilizzarlo in sessioni specifiche o script di shell dedicati.
Verifica dell'attivazione
Dalla versione 3.13 in poi, il modulo sys include il namespace sys._jit per l'introspezione. Ecco le tre utility fondamentali per verificare lo stato del compilatore:
- sys._jit.is_available(): Conferma se la build corrente supporta il JIT (assente nelle build "free-threaded").
- sys._jit.is_enabled(): Conferma se il JIT è attivo. Questo è il metodo più affidabile per i controlli preliminari.
- sys._jit.is_active(): Indica se il frame corrente dello stack sta eseguendo codice JITted. Meno affidabile per i test generali poiché il controllo stesso potrebbe avvenire in un percorso "freddo".
Il Benchmark: Il caso Mandelbrot
Poiché non esiste ancora una strumentazione utente per tracciare il JIT, l'unico metodo di validazione è il benchmarking comparativo. Il seguente script per il calcolo del frattale di Mandelbrot mostra guadagni consistenti.
from time import perf_counter
import sys
print("JIT enabled:", sys._jit.is_enabled())
WIDTH, HEIGHT = 80, 40
X_MIN, X_MAX = -2.0, 1.0
Y_MIN, Y_MAX = -1.0, 1.0
ITERS = 500
YM = (Y_MAX - Y_MIN)
XM = (X_MAX - X_MIN)
def iter(c):
z = 0j
for _ in range(ITERS):
if abs(z) > 2.0:
return False
z = z ** 2 + c
return True
def generate():
start = perf_counter()
output = []
for y in range(HEIGHT):
cy = Y_MIN + (y / HEIGHT) * YM
for x in range(WIDTH):
cx = X_MIN + (x / WIDTH) * XM
c = complex(cx, cy)
output.append("#" if iter(c) else ".")
output.append("\n")
print("Time:", perf_counter()-start)
return output
print("".join(generate()))
Eseguendo questo codice con il JIT abilitato, si nota un miglioramento delle prestazioni stabile attorno al 20%. Aumentare la variabile ITERS costringe il programma a un carico di lavoro maggiore, rendendo il divario ancora più evidente.