Python 3.11: 10-60% più veloce, exception groups, traceback raffinati

Python 3.11 (24 ottobre 2022): interpreter specializing adaptive (PEP 659), exception groups e except* (PEP 654), traceback con puntamento preciso, variadic generics (PEP 646). Il risultato dell'iniziativa Faster CPython di Microsoft con Mark Shannon e Guido van Rossum.

Open SourceWebR&D PythonPython 3.11PerformanceFaster CPythonMark ShannonGuido van RossumMicrosoftOpen Source

Il salto di prestazioni

Python 3.11 è stato rilasciato il 24 ottobre 2022 con un risultato che attira più attenzione di ogni novità sintattica: è significativamente più veloce della 3.10. I benchmark pubblici di pyperformance mostrano miglioramenti medi tra 10% e 60%, con alcuni casi che arrivano a speedup superiori.

Il risultato viene dall’iniziativa Faster CPython — programma avviato a fine 2020 quando Microsoft ha assunto Mark Shannon (storico contributore CPython) e poi Guido van Rossum stesso (da Microsoft, ritornato attivo sul core). L’obiettivo dichiarato: 5x più veloce in quattro release.

PEP 659 — Specializing Adaptive Interpreter

La chiave tecnica della 3.11 è PEP 659, che introduce un interpreter che si specializza dinamicamente in base ai tipi osservati a runtime. Come funziona:

  • Ogni bytecode generico (es. BINARY_OP per a + b) dopo alcune esecuzioni viene specializzato sulla base dei tipi concreti visti (es. BINARY_OP_ADD_INT, BINARY_OP_ADD_FLOAT, BINARY_OP_ADD_UNICODE)
  • Ogni opcode specializzato bypassa la risoluzione dinamica di tipo, saltando direttamente all’implementazione ottimizzata
  • Se i tipi cambiano, l’opcode torna alla versione generica (deoptimization)

Il risultato è un interprete che impara i pattern del codice caldo senza necessità di una compilazione JIT separata.

Altre ottimizzazioni contributo alla release:

  • Frame zero-cost — chiamate di funzione con overhead drasticamente ridotto
  • Faster startup — bytecode cache migliorato, interpreter startup più veloce
  • Exceptions zero-cost — il try non ha costo se non viene sollevata eccezione (vs. costo lineare in 3.10)
  • Smaller objects — rappresentazione più compatta di frame, int

Exception Groups (PEP 654)

Sintassi nuova per gestire gruppi di eccezioni simultanee, utile per concurrency (asyncio.gather), parser che accumulano errori multipli:

try:
    async with asyncio.TaskGroup() as tg:
        tg.create_task(task1())
        tg.create_task(task2())
        tg.create_task(task3())
except* ValueError as eg:
    # eg è un ExceptionGroup di tutte le ValueError sollevate
    for e in eg.exceptions:
        print(e)
except* TypeError as eg:
    # gestione separata per TypeError
    ...

La sintassi except* (nota come except star) cattura selettivamente dal gruppo, lasciando intatto ciò che non matcha. Integra con asyncio.TaskGroup (anch’esso nuovo in 3.11) che solleva automaticamente exception groups quando multiple task falliscono.

Fine-grained error locations (PEP 657)

Il traceback ora indica posizione precisa all’interno della riga, non solo il numero di riga:

Traceback (most recent call last):
  File "script.py", line 10, in <module>
    result = obj.attr1.attr2.method(a, b)
             ^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'attr1'

Il carato ^ indica esattamente l’espressione in errore. Cambiamento apparentemente piccolo ma di impatto pratico enorme per debugging di codice con espressioni complesse.

Typing: Self, LiteralString, variadic generics

Self type (PEP 673):

class Node:
    def clone(self) -> Self: ...
    # Self denota il tipo concreto del metodo corrente

LiteralString (PEP 675): type annotation per stringhe letterali, utile per prevenire SQL injection statica:

def execute_query(sql: LiteralString) -> ResultSet: ...

Variadic Generics (PEP 646): TypeVarTuple per generici con numero variabile di parametri, rilevante soprattutto per tipizzare tensor shapes in ML:

from typing import TypeVarTuple

Shape = TypeVarTuple("Shape")
class Tensor(Generic[*Shape]): ...

tomllib standard library

tomllib (PEP 680): parser TOML in standard library. Serve in particolare per gli strumenti di packaging Python che usano pyproject.toml. Rimuove la necessità di dipendere da toml/tomli per questo caso d’uso frequente.

Async & TaskGroup

La classe asyncio.TaskGroup (PEP introdotta nel 3.11) offre gestione strutturata di task concorrenti:

async def main():
    async with asyncio.TaskGroup() as tg:
        tg.create_task(fetch("a"))
        tg.create_task(fetch("b"))
    # Entrambe completate o entrambe cancellate su errore

Se un task fallisce, gli altri sono automaticamente cancellati; le eccezioni sono raggruppate in un ExceptionGroup.

Altri miglioramenti

  • asyncio.timeout() context manager per timeout strutturato
  • Contextvars integrati meglio con asyncio
  • WASI e Emscripten come target di build (Python nel browser via Pyodide/etc.)
  • tomllib in stdlib
  • Rimozione di moduli deprecati (binhex)

Implicazioni pratiche

Lo speedup della 3.11 ha impatto concreto:

  • Workload web (Django, FastAPI, Flask) — mediana 10-25% più veloce senza modifiche
  • Data processing (pandas su dati medi) — 15-30%
  • Scientific computing — dipende dal workload, spesso meno (NumPy già bypassa CPython su hot path)
  • Batch job — benefici netti se compute-bound in Python puro

L’adozione 3.11 è motivata anche solo dal beneficio prestazionale — non serve nuova sintassi per guadagnare.

Nel contesto italiano

Python 3.11 si diffonde più rapidamente del solito:

  • Data science team italiani — migrazione entro 6-12 mesi
  • Backend web — nuovi progetti su 3.11 da inizio 2023
  • Grandi SaaS italiani — rollout graduale con A/B per misurare speedup

Il tema Faster CPython continuerà in 3.12 (2023), 3.13 (2024, con free-threaded Python sperimentale) e oltre, confermando l’obiettivo di lungo periodo di migliorare sostanzialmente le prestazioni dell’interprete di riferimento.


Riferimenti: Python 3.11.0 (24 ottobre 2022). Faster CPython project (Microsoft, Mark Shannon + Guido van Rossum + team). PEP 659 (Specializing Adaptive Interpreter), PEP 654 (Exception Groups), PEP 657 (fine-grained error locations), PEP 673 (Self type), PEP 675 (LiteralString), PEP 646 (Variadic Generics), PEP 680 (tomllib).

Vuoi supporto? Sei sotto attacco? Stato dei servizi
Vuoi supporto? Sei sotto attacco? Stato dei servizi